public void CreateControlPoint( ) { CurvySplineSegment prevPoint = _spline.ControlPoints [_spline.ControlPointCount - 1]; _spline.Add(); CurvySplineSegment newPoint = _spline.ControlPoints [_spline.ControlPointCount - 1]; float angle = Mathf.Sin(Time.timeSinceLevelLoad); Vector3 axis = prevPoint.transform.forward; int distance = 4; //not working?? //_offsetQuat *= Quaternion.Euler (0.0f, 0.0f, Random.Range (-4.0f, 4.0f)); //newPoint.transform.localRotation = _offsetQuat; //newPoint.transform.localEulerAngles = new Vector3( (_spline.ControlPointCount * 10.0f ) % 360.0f, newPoint.transform.localEulerAngles.y, newPoint.transform.localEulerAngles.z ); //newPoint.transform.localEulerAngles = new Vector3( 10.0f * Mathf.Sin(_spline.ControlPointCount / 2.0f), newPoint.transform.localEulerAngles.y, Mathf.Cos(Random.Range (-0.03f, 0.03f)) ); newPoint.transform.localEulerAngles = new Vector3(newPoint.transform.localEulerAngles.x, 10.0f * Mathf.Sin(_spline.ControlPointCount / 2.0f), Mathf.Cos(Random.Range(-0.03f, 0.03f))); newPoint.transform.position = prevPoint.transform.position + newPoint.transform.forward * distance; //draw red debug lines out Vector3 rightPt = new Vector3(newPoint.transform.position.x + 20.0f, newPoint.transform.position.y, newPoint.transform.position.z); Vector3 leftPt = new Vector3(newPoint.transform.position.x - 20.0f, newPoint.transform.position.y, newPoint.transform.position.z); AxKDebugLines.AddLine(newPoint.transform.position, rightPt, Color.red, 9999999.0f); AxKDebugLines.AddLine(newPoint.transform.position, leftPt, Color.red, 9999999.0f); }
public static void ConnectionGizmo(CurvySplineSegment cp) { Matrix4x4 mat = Gizmos.matrix; Gizmos.matrix = Matrix; Color c = Color.black; if (cp.ConnectionSyncPosition) { if (cp.ConnectionSyncRotation) { c = Color.white; } else { c = Color.red; } } else if (cp.ConnectionSyncRotation) { c = new Color(1, 1, 0); } Gizmos.color = c; Vector3 p = cp.transform.localPosition; Gizmos.DrawWireSphere(p, DTUtility.GetHandleSize(p) * CurvyGlobalManager.GizmoControlPointSize * 1.3f); Gizmos.matrix = mat; }
/// <summary> /// Undo-complient version of CurvyUtility.SplitSpline() /// </summary> /// <param name="firstCP">the first Control Point of the new spline</param> /// <returns>the new spline</returns> public static CurvySpline UndoSplitSpline(CurvySplineSegment firstCP) { #if OLD_UNDO Undo.RegisterSceneUndo("Split Spline"); return(CurvyUtility.SplitSpline(firstCP)); #else CurvySpline old = firstCP.Spline; CurvySpline spl = CurvySpline.Create(old); Undo.RegisterCreatedObjectUndo(spl.gameObject, "Split Spline"); spl.name = old.name + "_parted"; // Move CPs var affected = old.ControlPoints.GetRange(firstCP.ControlPointIndex, old.ControlPointCount - firstCP.ControlPointIndex); for (int i = 0; i < affected.Count; i++) { Undo.RecordObject(affected[i].gameObject, "Split Spline"); Undo.SetTransformParent(affected[i].Transform, spl.Transform, "Split Spline"); affected[i]._ReSettle(); } old.ControlPoints.Clear(); old.RefreshImmediately(true, true, false); spl._RenameControlPointsByIndex(); spl.RefreshImmediately(true, true, false); return(spl); #endif }
/// <summary> /// Sets Bezier Handles by interpolating between Control Points /// </summary> /// <param name="interpolation">the interpolation to use</param> /// <param name="offset">the offset in F (0..1)</param> /// <param name="freeMoveHandles">whether Handles should be moved individually</param> /// <param name="controlPoints">the Control Points to set the Handles for</param> public static void InterpolateBezierHandles(CurvyInterpolation interpolation, float offset, bool freeMoveHandles, params CurvySplineSegment[] controlPoints) { if (controlPoints.Length == 0) { return; } offset = UnityEngine.Mathf.Clamp01(offset); foreach (CurvySplineSegment cp in controlPoints) { cp.FreeHandles = freeMoveHandles; CurvySplineSegment other = cp.PreviousSegment; if (other) { cp.HandleInPosition = other.Interpolate(1 - offset, interpolation); } else { cp.HandleInPosition = cp.Interpolate(0, interpolation); } if (freeMoveHandles) { if (cp.IsValidSegment) { cp.HandleOutPosition = cp.Interpolate(offset, interpolation); } else { cp.HandleInPosition = UnityEngine.Vector3.zero; } } } controlPoints[0].Spline.Refresh(); }
public static void SetFirstCP(CurvySplineSegment newStartCP) { if (newStartCP) { newStartCP.SetAsFirstCP(); } }
/// <summary> /// Undo-complient version of CurvyUtility.JoinSpline() /// </summary> /// <param name="sourceCP">a Control Point of the source spline</param> /// <param name="destCP">the Control Point of the destination spline</param> public static void UndoJoinSpline(CurvySplineSegment sourceCP, CurvySplineSegment destCP) { #if !OLD_UNDO if (!sourceCP || !destCP) { return; } CurvySpline src = sourceCP.Spline; CurvySpline dst = destCP.Spline; if (src == dst) { return; } for (int i = 0; i < src.ControlPointCount; i++) { Undo.RecordObject(src.ControlPoints[i].gameObject, "Join Spline"); Undo.SetTransformParent(src.ControlPoints[i].Transform, dst.Transform, "Join Spline"); src.ControlPoints[i]._ReSettle(); } dst.ControlPoints.InsertRange(destCP.ControlPointIndex + 1, src.ControlPoints); dst._RenameControlPointsByIndex(); dst.RefreshImmediately(true, true, false); Undo.DestroyObjectImmediate(src.gameObject); #endif }
/// <summary> /// Gets all Control Points except the one provided /// </summary> /// <param name="source">the Control Point to filter out</param> /// <returns>list of Control Points</returns> public List <CurvySplineSegment> OtherControlPoints(CurvySplineSegment source) { var res = new List <CurvySplineSegment>(ControlPoints); res.Remove(source); return(res); }
public void DeserializeInto(CurvySplineSegment controlPoint, CurvySerializationSpace space = CurvySerializationSpace.WorldSpline) { if (controlPoint) { #if UNITY_EDITOR Undo.RegisterCompleteObjectUndo(controlPoint, "Deserialize"); #endif if (space == CurvySerializationSpace.World) { controlPoint.position = P; controlPoint.rotation = Quaternion.Euler(R); } else { controlPoint.localPosition = P; controlPoint.localRotation = Quaternion.Euler(R); } controlPoint.AutoBakeOrientation = Bake; controlPoint.OrientationAnchor = Anchor; controlPoint.Swirl = Swirl; controlPoint.SwirlTurns = SwirlT; controlPoint.AutoHandles = BzAuto; controlPoint.AutoHandleDistance = BzAutoDist; controlPoint.SetBezierHandleIn(BzIn); controlPoint.SetBezierHandleOut(BzOut); } }
IEnumerator NavigationLine(float waitTime) { while (true) { yield return(new WaitForSeconds(waitTime)); CurvySpline curvySpline = pathEnhanced.GetComponent <CurvySpline>(); segmentsToSearch.Add(curSegment); segmentsToSearch.Add(curvySpline[curSegment.SegmentIndex + 1].GetComponent <CurvySplineSegment>()); segmentsToSearch.Add(curvySpline[curSegment.SegmentIndex - 1].GetComponent <CurvySplineSegment>()); //float carTf = curvySpline.GetNearestPointTFExt(transform.position, segmentsToSearch.ToArray()); float carTf = curvySpline.GetNearestPointTF(transform.position); Lane lane = MonitorLane(curvySpline.GetTangentFast(carTf)); if (lane == Lane.RIGHT) { linesUtilsAlt.DrawLine(gameObject, curvySpline, carTf); } else { linesUtilsAlt.LineRend.positionCount = 0; //delete the LineRenderer } curSegment = curvySpline.TFToSegment(carTf); segmentsToSearch.Clear(); } }
IEnumerator NavigationLine(float waitTime) { while (true) { yield return(new WaitForSeconds(waitTime)); //CurvySpline curvySpline = pathEnhanced.GetComponent<CurvySpline>(); segmentsToSearch.Add(curSegment); if (curSegment.SegmentIndex != curvySpline.Segments.Count - 1 && curSegment.SegmentIndex != 0) { segmentsToSearch.Add(curvySpline[curSegment.SegmentIndex + 1].GetComponent <CurvySplineSegment>()); segmentsToSearch.Add(curvySpline[curSegment.SegmentIndex - 1].GetComponent <CurvySplineSegment>()); } else if (curSegment.SegmentIndex == curvySpline.Segments.Count - 1) { segmentsToSearch.Add(curvySpline[0].GetComponent <CurvySplineSegment>()); } else if (curSegment.SegmentIndex == 0) { segmentsToSearch.Add(curvySpline[1].GetComponent <CurvySplineSegment>()); } float carTf = curvySpline.GetNearestPointTFExt(transform.position, segmentsToSearch.ToArray()); linesUtilsAlt.DrawLine(gameObject, curvySpline, carTf); curSegment = curvySpline.TFToSegment(carTf); segmentsToSearch.Clear(); //else if (linesUtilsAlt.LineRend.positionCount != 0) // linesUtilsAlt.LineRend.positionCount = 0; //delete the LineRenderer } }
void doFollowUpPopup(Rect r, CurvySplineSegment item) { var possibleTargets = (from cp in Target.ControlPoints where cp != item select cp).ToList(); int sel = possibleTargets.IndexOf(item.FollowUp) + 1; var content = (from cp in possibleTargets select cp.ToString()).ToList(); content.Insert(0, " "); EditorGUI.BeginChangeCheck(); if (item.FollowUp && item.FollowUp.gameObject == Selection.activeGameObject) { DTHandles.DrawSolidRectangleWithOutline(r.ScaleBy(2, 0).ShiftBy(1, -2), new Color(0f, 0, 0, 0.1f), new Color(.24f, .37f, .59f)); } sel = EditorGUI.Popup(r, sel, content.ToArray()); if (EditorGUI.EndChangeCheck()) { if (sel > 0) { item.SetFollowUp(possibleTargets[sel - 1]); } else { item.SetFollowUp(null); } } }
void ConnectionDetailsGUI(CurvySplineSegment seg) { if (!seg || seg.Connection == null) { return; } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button(new GUIContent(mTexSelect, "Select Other"), GUILayout.ExpandWidth(false))) { Selection.activeObject = (seg == Target) ? seg.Connection.Other : seg; } EditorGUILayout.LabelField(seg.Spline.name + "->" + seg.Connection.Other.Spline.name + "." + seg.Connection.Other.name); if (GUILayout.Button(new GUIContent(mTexDelete, "Delete Connection"), GUILayout.ExpandWidth(false))) { Undo.RegisterSceneUndo("Delete Connection"); seg.ConnectTo(null); SceneView.RepaintAll(); return; } EditorGUILayout.EndHorizontal(); seg.Connection.Heading = (CurvyConnection.HeadingMode)EditorGUILayout.EnumPopup(new GUIContent("Heading", "Heading Mode"), seg.Connection.Heading); seg.Connection.Sync = (CurvyConnection.SyncMode)EditorGUILayout.EnumPopup(new GUIContent("Synchronization", "Synchronization Mode"), seg.Connection.Sync); seg.Connection.Tags = EditorGUILayout.TextField(new GUIContent("Tags", "Identifier tags (space separated)"), seg.Connection.Tags); if (GUI.changed) { seg.SyncConnections(); if (seg.Connection.Active) { seg.Connection.Other.Spline.Refresh(); } } GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1)); }
/// <summary> /// Checks if the connection is valid. If not, it will be disconnected /// </summary> public void Validate() { if (Active && !Other.ConnectedBy.Contains(Owner)) { Owner = null; Other = null; } }
/// <summary> /// Removes a Control Point from this connection /// </summary> /// <param name="controlPoint">the Control Point to remove</param> /// <param name="destroySelfIfEmpty">whether the connection should be destroyed when empty afterwards</param> public void RemoveControlPoint(CurvySplineSegment controlPoint, bool destroySelfIfEmpty = true) { controlPoint.Connection = null; ControlPoints.Remove(controlPoint); if (ControlPoints.Count == 0 && destroySelfIfEmpty) { Delete(); } }
public CurvySplineMoveEventArgs(MonoBehaviour sender, CurvySpline spline, CurvySplineSegment cp, float tf, float delta, int dir, bool worldUnits = false) : base(sender, spline, cp) { Sender = sender; Direction = dir; Delta = delta; TF = tf; WorldUnits = worldUnits; }
/// <summary> /// Clear this connection /// </summary> public void Disconnect() { if (Active) { Other.ConnectedBy.Remove(Owner); } Owner = null; Other = null; }
public void CreateControlPoint(Transform playerTransform) { _spline.Add(); CurvySplineSegment newPoint = _spline.ControlPoints [_spline.ControlPointCount - 1]; newPoint.transform.localEulerAngles = new Vector3(playerTransform.localEulerAngles.x, playerTransform.localEulerAngles.y, playerTransform.localEulerAngles.z); newPoint.transform.position = playerTransform.position; }
/// <summary> /// Sets the options of this connection /// </summary> /// <param name="me">Owner of the connection</param> /// <param name="other">the partner Control Point </param> /// <param name="heading">the heading mode</param> /// <param name="sync">the synchronization mode</param> /// <param name="tags">tags of this connection</param> public void Set(CurvySplineSegment me, CurvySplineSegment other, HeadingMode heading, SyncMode sync, params string[] tags) { Owner = me; Other = other; Other.ConnectedBy.Add(me); Heading = heading; Sync = sync; SetTags(tags); }
/// <summary> /// Builds a mesh from a spline's approximation points (2D) /// </summary> /// <param name="spline">the spline to use</param> /// <param name="ignoreAxis">the axis to ignore (0=x,1=y,2=z)</param> /// <param name="close">True to create a mesh with triangles, False to create a vertex line mesh</param> /// <param name="msh"></param> public static Mesh CreateSplineMesh(CurvySpline spline, int ignoreAxis, bool close, Mesh msh = null) { Vector3[] verts = spline.GetApproximation(true); if (spline.Closed) { CurvySplineSegment.Resize(ref verts, verts.Length - 1); } return(buildSplineMesh(verts, ignoreAxis, !close, msh)); }
public static void BoundsGizmo(CurvySplineSegment cp, Color col) { Matrix4x4 mat = Gizmos.matrix; Gizmos.matrix = Matrix; Gizmos.color = col; Gizmos.DrawWireCube(cp.Bounds.center, cp.Bounds.size); Gizmos.matrix = mat; }
internal void SetStartPoint(CurvySplineSegment s) { if (start == null) { start = (Transform)Instantiate(res.startPrefab); start.name = res.startPrefab.name; } start.position = s.Position + Vector3.up * 3 + s.transform.forward * 6; start.rotation = s.transform.rotation; start.parent = s.transform; }
IEnumerator InitNavigationLine() { curvySpline = pathEnhanced.GetComponent <CurvySpline>(); while (!curvySpline.IsInitialized) { yield return(null); } float carTf = curvySpline.GetNearestPointTF(transform.position); curSegment = curvySpline.TFToSegment(carTf); }
public static void Deserialize(string json, CurvySplineSegment insertAfter, CurvySerializationSpace space) { if (SerializedCurvyObjectHelper.GetJsonSerializedType(json) == typeof(SerializedCurvySplineSegmentCollection)) { var sspl = SerializedCurvySplineSegmentCollection.FromJson(json); sspl.Deserialize(insertAfter, space, mOnDeserializedCP); } else { DTLog.LogWarning("[Curvy] CurvyImportExport.Deserialize: Data isn't of type 'SerializedCurvySplineSegmentCollection'!"); } }
public CurvySplineSegment Deserialize(CurvySplineSegment controlPoint, CurvySerializationSpace space = CurvySerializationSpace.WorldSpline) { if (controlPoint) { var cp = controlPoint.Spline.InsertAfter(controlPoint); #if UNITY_EDITOR Undo.RegisterCreatedObjectUndo(cp.gameObject, "Deserialize"); #endif DeserializeInto(cp, space); return(cp); } return(null); }
/// <summary> /// Connect this Control Point to another Control Point or remove an existing connection initiated by this Control Point /// </summary> /// <remarks>Set targetCP to null to remove an existing connection</remarks> /// <param name="targetCP">the Control Point to connect to, or null to release a connection initiated by this Control Point</param> /// <param name="heading">the connection type</param> /// <param name="sync">the connection mode</param> /// <param name="tags">any number of tags to assign to this junction</param> public void ConnectTo(CurvySplineSegment targetCP, CurvyConnection.HeadingMode heading, CurvyConnection.SyncMode sync, params string[] tags) { var con = Connection; if (con != null) { Connection.Disconnect(); } if (targetCP) { mConnection.Set(this, targetCP, heading, sync, tags); } }
/*! \cond PRIVATE */ void addControlPoint(CurvySplineSegment controlPoint) { if (!controlPoint.Connection) { #if UNITY_EDITOR if (!Application.isPlaying) { Undo.RecordObject(controlPoint, "Add Connection"); } #endif m_ControlPoints.Add(controlPoint); controlPoint.Connection = this; } }
public void SetCheckPoint(CurvySplineSegment segment) { var ch = (Transform)Instantiate(res.CheckPoint); ch.name = res.CheckPoint.name; ch.position = segment.Position; ch.rotation = segment.transform.rotation; ch.parent = segment.transform; if (finnish) { ch.name = "Finnish"; } finnish = false; }
/// <summary> /// Internal, don't call directly /// </summary> public void _InitializeControlPoint() { //mNextControlPoint = NextControlPoint; mStepSize = 1f / Spline.Granularity; mControlPointIndex = Spline.ControlPoints.IndexOf(this); Approximation = new Vector3[0]; ApproximationDistances = new float[0]; ApproximationUp = new Vector3[0]; ApproximationT = new Vector3[0]; if (UserValues.Length != Spline.UserValueSize) { CurvySplineSegment.Resize(ref UserValues, Spline.UserValueSize); } }
public static void SegmentApproximationGizmo(CurvySplineSegment seg, Color col) { Matrix4x4 mat = Gizmos.matrix; Gizmos.matrix = Matrix; Gizmos.color = col; Vector3 size = new Vector3(0.1f/seg.Spline.transform.localScale.x, 0.1f/seg.Spline.transform.localScale.y, 0.1f/seg.Spline.transform.localScale.z); for (int i=0;i<seg.Approximation.Length;i++){ Vector3 p=seg.Approximation[i]; Gizmos.DrawCube(p, DTUtility.GetHandleSize(p)*size); } Gizmos.matrix = mat; }
/// <summary> /// Gets the other Control Point /// </summary> /// <param name="cp">a ControlPoint being part of this connection</param> /// <returns>Either Owner, Other or Null</returns> public CurvySplineSegment GetCounterpart(CurvySplineSegment cp) { if (Owner == cp) { return(Other); } else if (Other == cp) { return(Owner); } else { return(null); } }
public MeshInfo(Mesh mesh, bool calculateLoops, bool mirror) { if (mirror) { mesh = MirrorMesh(mesh); } Vector3[] vt = mesh.vertices; Vector2[] uv = mesh.uv; int[] tri = mesh.triangles; // Fill data arrays Vertices = new Vector3[vt.Length]; UVs = new Vector2[uv.Length]; Triangles = new int[tri.Length]; vt.CopyTo(Vertices, 0); uv.CopyTo(UVs, 0); tri.CopyTo(Triangles, 0); if (calculateLoops) { // Build Edge Loops EdgeLoops = MeshHelper.BuildEdgeLoops(MeshHelper.BuildManifoldEdges(mesh)); // Fill Outline Data EdgeVertices = new Vector3[vt.Length]; EdgeUV = new Vector2[uv.Length]; int minIndex = int.MaxValue; int vertsUsed = 0; foreach (EdgeLoop loop in EdgeLoops) { for (int vi = 0; vi < loop.vertexCount; vi++) { EdgeVertices[vertsUsed + vi] = vt[loop.vertexIndex[vi]]; EdgeUV[vertsUsed + vi] = uv[loop.vertexIndex[vi]]; minIndex = Mathf.Min(minIndex, loop.vertexIndex[vi]); } vertsUsed += loop.vertexCount; } // modify EdgeLoops' indices (we need to address changed indices by omitting non-outlined edges foreach (EdgeLoop loop in EdgeLoops) { loop.ShiftIndices(-minIndex); } CurvySplineSegment.Resize(ref EdgeVertices, vertsUsed); CurvySplineSegment.Resize(ref EdgeUV, vertsUsed); } }
public static void SegmentOrientationAnchorGizmo(CurvySplineSegment seg, Color col) { if (seg.ApproximationUp.Length == 0) return; Matrix4x4 mat = Gizmos.matrix; Gizmos.matrix = Matrix; Gizmos.color = col; Vector3 scl = new Vector3(1 / seg.Spline.transform.localScale.x, 1 / seg.Spline.transform.localScale.y, 1 / seg.Spline.transform.localScale.z); Vector3 u = seg.ApproximationUp[0]; u.Set(u.x * scl.x, u.y * scl.y, u.z * scl.z); Gizmos.DrawRay(seg.Approximation[0], u * CurvyGlobalManager.GizmoOrientationLength * 1.75f); Gizmos.matrix = mat; }
void Init(GameObject o) { if (o) Target = o.GetComponent<CurvySplineSegment>(); else Target = null; if (Target) { if (maxLength == 0) maxLength = Target.Spline.Length; xCon = CurvySplineSegmentInspector.ConstrainXAxis; yCon = CurvySplineSegmentInspector.ConstrainYAxis; zCon = CurvySplineSegmentInspector.ConstrainZAxis; } }
public static void SegmentOrientationGizmo(CurvySplineSegment seg, Color col) { Matrix4x4 mat = Gizmos.matrix; Gizmos.matrix = Matrix; Gizmos.color = col; Vector3 scl = new Vector3(1 / seg.Spline.transform.localScale.x, 1 / seg.Spline.transform.localScale.y, 1 / seg.Spline.transform.localScale.z); Vector3 u; for (int i = 0; i < seg.ApproximationUp.Length; i++) { u = seg.ApproximationUp[i]; u.Set(u.x * scl.x, u.y * scl.y, u.z * scl.z); Gizmos.DrawRay(seg.Approximation[i], u * CurvyGlobalManager.GizmoOrientationLength); } Gizmos.matrix = mat; }
public static void SegmentCurveGizmo(CurvySplineSegment seg, Color col, float stepSize=0.05f) { Matrix4x4 mat = Gizmos.matrix; Gizmos.matrix = Matrix; Gizmos.color = col; if (seg.Spline.Interpolation == CurvyInterpolation.Linear) { Gizmos.DrawLine(seg.Interpolate(0), seg.Interpolate(1)); return; } Vector3 p = seg.Interpolate(0); for (float f = stepSize; f < 1; f += stepSize) { Vector3 p1 = seg.Interpolate(f); Gizmos.DrawLine(p, p1); p = p1; } Gizmos.DrawLine(p, seg.Interpolate(1)); Gizmos.matrix = mat; }
private void CopyFrom(CurvySplineSegment segment, Vector3 position) { swirl = segment.swirl; scale = segment.scale; flying = segment.flying; spline = (CurvySpline2)segment.Spline; if (spline.shape) { //color = spline.color; materialId = spline.materialId; } //selectedColorTexture = pickTexture = null; //selectedShapes = segment.spls; if (Math.Abs(position.y - cursor.position.y) > .01f) { cursor.position = position; cursor.position = GetPoint(); } }
/// <summary> /// Deletes a Control Point /// </summary> /// <param name="controlPoint">a Control Point</param> /// <param name="refreshSpline">whether the spline should refresh</param> public void Delete(CurvySplineSegment controlPoint, bool refreshSpline) { mControlPoints.Remove(controlPoint); controlPoint.name = "pendingDelete"; // IMPORTANT! Runtime Delete is delayed, so we need to make sure it got sorted to the end on RefreshImmediately() if (Application.isPlaying) Destroy(controlPoint.gameObject); else DestroyImmediate(controlPoint.gameObject); _RenameControlPointsByIndex(); if (refreshSpline) RefreshImmediately(); }
/// <summary> /// Gets the TF value that is nearest to p for a given set of segments /// </summary> /// <param name="p">a point in space</param> /// <param name="segmentsToCheck">the segments to check</param> /// <remarks>The speed as well as the accuracy depends on the Granularity</remarks> /// <returns>a TF value in the range 0..1 or -1 on error</returns> public float GetNearestPointTFExt(Vector3 p, params CurvySplineSegment[] segmentsToCheck) { if (Count == 0 || segmentsToCheck.Length==0) return -1; float dist = float.MaxValue; int foundIndex=0; CurvySplineSegment foundSeg=null; float cur; for (int i = 0; i < segmentsToCheck.Length; i++) { for (int ap = 0; ap < segmentsToCheck[i].Approximation.Length; ap++) { cur = (segmentsToCheck[i].Approximation[ap] - p).sqrMagnitude; if (cur < dist) { dist = cur; foundIndex = ap; foundSeg = segmentsToCheck[i]; } } } // foundIndex is the nearest mApproximation point, check against the two lines this index belongs to //return foundSeg.LocalFToTF(foundSeg.getApproximationLocalF(foundIndex)); CurvySplineSegment[] pseg=new CurvySplineSegment[3]; int[] pidx = new int[3]; pseg[1] = foundSeg; pidx[1] = foundIndex; if (!getPreviousApproximationPoint(foundSeg, foundIndex, out pseg[0], out pidx[0],ref segmentsToCheck)){ pseg[0] = pseg[1]; pidx[0] = pidx[1]; } if (!getNextApproximationPoint(foundSeg, foundIndex, out pseg[2], out pidx[2], ref segmentsToCheck)) { pseg[2] = pseg[1]; pidx[2] = pidx[1]; } float[] frag=new float[2]; float[] ldist=new float[2]; ldist[0] = LinePointDistanceSqr(pseg[0].Approximation[pidx[0]], pseg[1].Approximation[pidx[1]], p, out frag[0]); ldist[1] = LinePointDistanceSqr(pseg[1].Approximation[pidx[1]], pseg[2].Approximation[pidx[2]], p, out frag[1]); if (ldist[0] < ldist[1]) { return pseg[0].LocalFToTF(pseg[0]._getApproximationLocalF(pidx[0]) + frag[0] * mStepSize); } else { return pseg[1].LocalFToTF(pseg[1]._getApproximationLocalF(pidx[1]) + frag[1] * mStepSize); } }
public void Update() { UpdateAlways(); if (windowHit) /*window hit*/ return; if ((!(onHeight && (mouseButton0 || shift)) && !android) || (android && mouseButtonAny)) cursor.position = GetPoint(); if (mouseScroll != 0) UpdateHeight(mouseScroll * 3, true); if (!scriptRefresh) foreach (SplinePathMeshBuilder a in FindObjectsOfType(typeof(SplinePathMeshBuilder))) a.Refresh(); scriptRefresh = true; if (KeyDebug(KeyCode.Alpha1, "break")) Debug.Break(); var segments = splines.Where(a => !a.shape).SelectMany(a => a.Segments); np = segments.Where(a => a.dist < 10) .OrderBy(a => a.z).FirstOrDefault(); if (np == null) np = segments.Where(a => a.dist != MaxValue).OrderBy(a => a.dist).FirstOrDefault(); if (np != null) { np.point = np.Spline2.Interpolate(np.Spline2.GetNearestPointTF(np.pivot)); Debug.DrawLine(cursorPos, np.pivot, Color.blue); } if (!mouseButton0 || mouseButtonDown0 && android) //if (np != null && !np.Spline2.shape && !android && (np.pivot - pos).magnitude < 1000) // rotateCamPivot = np.pivot; //else rotateCamPivot = GetPoint(); if (Input.GetKeyDown(KeyCode.Z) && segment != null && (segment.NextControlPoint == null)) { if (segment.Spline.Closed && enableClosed2) segment.Spline.Closed = false; else Remove(segment.gameObject); } if (Input.GetKeyDown(KeyCode.Delete) && spline != null) Destroy(spline.gameObject); if (mouseButton0 && draw) { Cursor.SetCursor(_Loader.guiSkins.updownCursor, Vector2.one * 16, CursorMode.Auto); } else Cursor.SetCursor(null, Vector3.zero, CursorMode.Auto); if (mouseButton0 && (alt || tool == Tool.CameraRotate)) { //if ((rotateCamPivot - pos).magnitude < 600) { transform.RotateAround(rotateCamPivot, Vector3.up, mouseDelta.x * 10); transform.RotateAround(rotateCamPivot, transform.right, -mouseDelta.y * 5); } } if (mouseButton1 /*&& (alt || draw||tool == Tool.Models)*/ || mouseButton0 && tool == Tool.CameraZoom) if (!shapeEditor) pos += transform.forward * (mouseDelta.y) * scaleFactor * 2; else shapeCamera.orthographicSize += mouseDelta.y; if (alt) /***********************alt*/ return; UpdateCheckPoint(); UpdateModelView(); hitTestSegment = null; if (tool != Tool.Brush && tool != Tool.BrushErase && tool != Tool.CheckPoint)//&& (!android || tool != Tool.Draw || segment == null) { if (android) hitTest = Physics.SphereCast(ray, 3, out hit, 1000, 1 << Layer.node); else hitTest = Physics.Raycast(ray, out hit, 1000, 1 << Layer.node); if (hitTest) hitTestSegment = hit.transform.parent.GetComponent<CurvySplineSegment>(); if (hitTest && mouseButtonUp1 && (Input.mousePosition - mouseDrag).magnitude < 3) { var checkPoint = getCheckPoint(hit.transform.parent); if (checkPoint) Destroy(checkPoint.gameObject); else Remove(hit.transform.parent.gameObject); return; } if (mouseButtonDown0) { if (hitTest) { CurvySplineSegment s = hit.transform.parent.GetComponent<CurvySplineSegment>(); if (enableClosed2) if (segment != null && s != segment && s.isEnd && segment.isEnd && s.Spline == segment.Spline && draw && !s.Spline2.shape && segment.Spline2.Count > 2) { s.Spline.Closed = true; s.Spline.Update(); print("Close"); return; } segment = s; drag = segment.transform; //heightScroll = 0; CopyFrom(segment, segment.Position); segment.dragOffset = drag.position - cursor.position; if (draw) return; } else if (!drawRoad) segment = null; //else if ((tool == Tool.CheckPoint || tool == Tool.StartPoint) && mouseButtonDown0) //Popup2("You must click on white sphere to add " + tool, OnEditorWindow); } } if (!mouseButton0) drag = null; if (onHeight && (mouseButton0 || shift)) { UpdateHeight(mouseDelta.y, drag == null); if (tool != Tool.Height) return; } if (np != null && np.dist < 100 && drag == null) { var sg = np; if (!mouseButtonDown0) { if (mouseButton0 && tool == Tool.Brush) { //foreach (var a in brushShapes) // if (!sg.spls.Contains(a)) // sg.spls.Add(a); sg.spls = brushShapes.ToList(); } //if (mouseButton0 && tool == Tool.BrushErase) //{ // foreach (var a in brushShapes) // sg.spls.Remove(a); //} } if (tool == Tool.Insert && mouseButtonDown0) { CopyFrom(sg, np.point); AddPoint(np.point, sg, false, true); return; } } if (segment != null) { var delta = mouseDelta.y; if (mouseButton0 && drag != null && onRotate) { if (affectNext || affectPrev) { foreach (var a in GetAffectBy()) a.transform.RotateAround(segment.transform.position, Vector3.up, delta * 6); } else { swirl += delta * 3; UpdateSwirl(); } } if (mouseButton0 && onScale && drag != null) { UpdateScale(delta); scale += delta; } if (mouseButton0 && onMove && drag != null) { var d = cursorPos - segment.Position + segment.dragOffset; foreach (CurvySplineSegment a in GetAffectBy()) a.Position += d; } //if (mouseButtonUp0 && tool == Tool.CheckPoint && !getCheckPoint(segment.transform) && hitTest) //{ // if (start == null || CheckStartPoint(start.position, segment.Position)) // SetCheckPoint(segment); //} //if (tool == Tool.StartPoint) //{ // if (mouseButton0 && drag != null) // { // SetStartPoint(segment); // start.LookAt(mousePos + segment.transform.forward * 10 + segment.transform.up * 3); // } //} } if (mouseButtonDown0) { //if (tool == Tool.Height || advanced) //{ if (draw) { if ((segment == null || segment.PreviousControlPoint == null || segment.NextControlPoint == null)) { if (shapeEditor) mapSets.usedAdvancedTools = true; if (segment == null) StartCoroutine(CreateSpline(delegate { AddPoint(cursorPos, null); }, shapeEditor)); else { if (brushShapes.Count == 0) brushShapes.Add(shapes[0]); var b = Vector3.Dot(segment.transform.forward, (cursorPos - segment.Position).normalized) > 0 || segment.IsFirstSegment || segment.IsLastSegment; AddPoint(cursorPos, b ? segment : segment.PreviousControlPoint, segment == segment.Spline.ControlPoints[0] && segment.Spline.ControlPoints.Count > 1); return; } } else Reset(); } //} //else if (tool != Tool.Insert && tool != Tool.CheckPoint && tool != Tool.StartPoint && tool != Tool.Brush) //{ // Popup("To " + tool + " road please click and drag white sphere", OnEditorWindow, 600, 250); //} } if (mouseButtonUp1 && win.mouseDrag < (android ? 5 : 1) / 1024f) Reset(); UpdateSwirl2(); }
bool getNextApproximationPoint(CurvySplineSegment seg, int idx, out CurvySplineSegment res, out int residx, ref CurvySplineSegment[] validSegments) { residx = idx + 1; res = seg; if (residx == seg.Approximation.Length) { res = NextSegment(seg); if (res) { residx = 1; for (int i = 0; i < validSegments.Length; i++) if (validSegments[i] == res) return true; } return false; } return true; }
/// <summary> /// Rearrange the spline to have a new first Control Point. /// </summary> /// <param name="newStartCP">the Control Point to become the first Control Point</param> public static void setFirstCP(CurvySplineSegment newStartCP) { CurvySpline spl = newStartCP.Spline; if (newStartCP.ControlPointIndex == 0) return; CurvySplineSegment[] toMove = new CurvySplineSegment[newStartCP.ControlPointIndex]; for (int i = 0; i < newStartCP.ControlPointIndex; i++) toMove[i] = spl.ControlPoints[i]; foreach (CurvySplineSegment seg in toMove) { spl.ControlPoints.Remove(seg); spl.ControlPoints.Add(seg); } spl._nameControlPoints(); spl.Refresh(); }
public CurvyConnection() { Owner = null; Other = null; }
/// <summary> /// Gets the previous segment of a certain segment /// </summary> /// <param name="segment">a segment</param> /// <returns>a segment or null</returns> public CurvySplineSegment PreviousSegment(CurvySplineSegment segment) { if (mSegments.Count == 0) return null; if (segment.SegmentIndex==-1) { int cp = segment.ControlPointIndex - 1; if (cp >= 0 && mControlPoints[cp].SegmentIndex > -1) return mControlPoints[cp]; else return null; } int i = segment.SegmentIndex - 1; if (i < 0) return (Closed) ? mSegments[mSegments.Count - 1] : null; else return (i<Count) ? mSegments[i] : null; }
/// <summary> /// Gets the previous Control Point of a certain Control Point /// </summary> /// <param name="controlpoint">a Control Point</param> /// <returns>a Control Point or null</returns> public CurvySplineSegment PreviousControlPoint(CurvySplineSegment controlpoint) { if (mControlPoints.Count == 0) return null; int i = controlpoint.ControlPointIndex - 1; if (i < 0) { if (Closed) return mControlPoints[mControlPoints.Count - 1]; else return null; } else return mControlPoints[i]; }
/// <summary> /// Gets the previous Transform of a certain Control Point /// </summary> /// <param name="controlpoint">a Control Point </param> /// <returns>a Transform or Null</returns> public Transform PreviousTransform(CurvySplineSegment controlpoint) { CurvySplineSegment seg = PreviousControlPoint(controlpoint); if (seg) return seg.Transform; else if (AutoEndTangents && Interpolation != CurvyInterpolation.Linear && Interpolation!= CurvyInterpolation.Bezier) return controlpoint.Transform; return null; }
/// <summary> /// Gets a TF value from a segment /// </summary> /// <param name="segment">a segment</param> /// <returns>a TF value in the range 0..1</returns> public override float SegmentToTF(CurvySplineSegment segment) { return SegmentToTF(segment, 0); }
/// <summary> /// Gets a TF value from a segment and a local F /// </summary> /// <param name="segment">a segment</param> /// <param name="localF">F of this segment in the range 0..1</param> /// <returns>a TF value in the range 0..1</returns> public override float SegmentToTF(CurvySplineSegment segment, float localF) { if (!segment) return 0; if (segment.SegmentIndex == -1) return (segment.ControlPointIndex > 0) ? 1 : 0; return ((float)segment.SegmentIndex / Count) + (1f / Count) * localF; }
/// <summary> /// Clear this connection /// </summary> public void Disconnect() { if (Active) Other.ConnectedBy.Remove(Owner); Owner = null; Other = null; }
/// <summary> /// Deletes a Control Point /// </summary> /// <param name="controlPoint">a Control Point</param> public void Delete(CurvySplineSegment controlPoint) { Delete(controlPoint, true); }
/// <summary> /// Gets the other Control Point /// </summary> /// <param name="cp">a ControlPoint being part of this connection</param> /// <returns>Either Owner, Other or Null</returns> public CurvySplineSegment GetCounterpart(CurvySplineSegment cp) { if (Owner == cp) return Other; else if (Other == cp) return Owner; else return null; }
bool iterateApproximationPoints(ref CurvySplineSegment seg, ref int idx) { idx++; if (idx == seg.Approximation.Length) { seg = NextSegment(seg); idx = 1; return (seg != null && !seg.IsFirstSegment); } return true; }
bool getPreviousApproximationPoint(CurvySplineSegment seg, int idx, out CurvySplineSegment res, out int residx, ref CurvySplineSegment[] validSegments) { residx = idx - 1; res = seg; if (residx <0) { res = PreviousSegment(seg); if (res) { residx = res.Approximation.Length - 2; for (int i = 0; i < validSegments.Length; i++) if (validSegments[i] == res) return true; return false; } return (false); } return true; }
/// <summary> /// Undo-complient version of CurvyUtility.JoinSpline() /// </summary> /// <param name="sourceCP">a Control Point of the source spline</param> /// <param name="destCP">the Control Point of the destination spline</param> public static void UndoJoinSpline(CurvySplineSegment sourceCP, CurvySplineSegment destCP) { #if !OLD_UNDO if (!sourceCP || !destCP) return; CurvySpline src = sourceCP.Spline; CurvySpline dst = destCP.Spline; if (src == dst) return; for (int i = 0; i < src.ControlPointCount; i++) { Undo.RecordObject(src.ControlPoints[i].gameObject, "Join Spline"); Undo.SetTransformParent(src.ControlPoints[i].Transform, dst.Transform, "Join Spline"); src.ControlPoints[i]._ReSettle(); } dst.ControlPoints.InsertRange(destCP.ControlPointIndex + 1, src.ControlPoints); dst._RenameControlPointsByIndex(); dst.RefreshImmediately(true, true, false); Undo.DestroyObjectImmediate(src.gameObject); #endif }
/// <summary> /// Adds a Control Point and refreshes the spline /// </summary> /// <param name="insertAfter">an ancestor Control Point</param> /// <returns>a Control Point</returns> public CurvySplineSegment Add(CurvySplineSegment insertAfter) { return Add(insertAfter, true); }
/// <summary> /// Adds a Control Point /// </summary> /// <remarks>If you add several Control Points in a row, just refresh the last one!</remarks> /// <param name="insertAfter">an ancestor Control Point. If null, the CP will added at the end</param> /// <param name="refresh">whether the spline should be recalculated.</param> /// <returns>a Control Point</returns> public CurvySplineSegment Add(CurvySplineSegment insertAfter, bool refresh) { GameObject go = new GameObject("NewCP", typeof(CurvySplineSegment)); go.transform.parent = transform; CurvySplineSegment cp = go.GetComponent<CurvySplineSegment>(); int idx = mControlPoints.Count; if (insertAfter) { if (insertAfter.IsValidSegment) go.transform.position = insertAfter.Interpolate(0.5f); else if (insertAfter.NextTransform) go.transform.position = Vector3.Lerp(insertAfter.NextTransform.position, insertAfter.Transform.position, 0.5f); idx = insertAfter.ControlPointIndex + 1; } mControlPoints.Insert(idx,cp); _RenameControlPointsByIndex(); if (refresh) RefreshImmediately(); return cp; }
/// <summary> /// Adds several Control Points at once and refresh the spline /// </summary> /// <param name="controlPoints">one or more positions</param> /// <returns>an array containing the new Control Points</returns> public CurvySplineSegment[] Add(params Vector3[] controlPoints) { CurvySplineSegment[] cps = new CurvySplineSegment[controlPoints.Length]; for (int i = 0; i < controlPoints.Length; i++) { cps[i] = Add(null, false); cps[i].Position = controlPoints[i]; } _RenameControlPointsByIndex(); RefreshImmediately(); return cps; }
/// <summary> /// Undo-complient version of CurvyUtility.SplitSpline() /// </summary> /// <param name="firstCP">the first Control Point of the new spline</param> /// <returns>the new spline</returns> public static CurvySpline UndoSplitSpline(CurvySplineSegment firstCP) { #if OLD_UNDO Undo.RegisterSceneUndo("Split Spline"); return CurvyUtility.SplitSpline(firstCP); #else CurvySpline old = firstCP.Spline; CurvySpline spl = CurvySpline.Create(old); Undo.RegisterCreatedObjectUndo(spl.gameObject, "Split Spline"); spl.name = old.name + "_parted"; // Move CPs var affected = old.ControlPoints.GetRange(firstCP.ControlPointIndex, old.ControlPointCount - firstCP.ControlPointIndex); for (int i = 0; i < affected.Count; i++) { Undo.RecordObject(affected[i].gameObject, "Split Spline"); Undo.SetTransformParent(affected[i].Transform, spl.Transform, "Split Spline"); affected[i]._ReSettle(); } old.ControlPoints.Clear(); old.RefreshImmediately(true, true, false); spl._RenameControlPointsByIndex(); spl.RefreshImmediately(true, true, false); return spl; #endif }
/// <summary> /// Adds a Control Point /// </summary> /// <remarks>If you add several Control Points in a row, just refresh the last one!</remarks> /// <param name="refresh">whether the spline should be recalculated.</param> /// <param name="insertBefore">an descendant Control Point</param> /// <returns>a Control Point</returns> public CurvySplineSegment Add(bool refresh, CurvySplineSegment insertBefore) { GameObject go = new GameObject("NewCP", typeof(CurvySplineSegment)); go.transform.parent = transform; CurvySplineSegment cp = go.GetComponent<CurvySplineSegment>(); int idx = 0; if (insertBefore) { if (insertBefore.PreviousSegment) go.transform.position = insertBefore.PreviousSegment.Interpolate(0.5f); else if (insertBefore.PreviousTransform) go.transform.position = Vector3.Lerp(insertBefore.PreviousTransform.position, insertBefore.Transform.position, 0.5f); idx = Mathf.Max(0,insertBefore.ControlPointIndex); } mControlPoints.Insert(idx, cp); _RenameControlPointsByIndex(); if (refresh) RefreshImmediately(); return cp; }