/// <summary> /// Divides the Current Section in half /// </summary> public void InsertSection() { int CurrIdx = BezCtrlPt.Current.CtrlPtId; int newSectnIdx = CurrIdx + 1; iRoadSectn CurrSectn = Rd.Sectns[CurrIdx]; int CurrSectnSegStartId = BezCtrlPt.Current.SegStartIdx; int CurrSectnSegCount = BezCtrlPt.Current.SegCount; int CurrSectnNewSegCount = CurrSectnSegCount / 2; int NewSectnSegStartId = CurrSectnSegStartId + CurrSectnNewSegCount; int NewSectnSegCount = CurrSectnSegCount - CurrSectnNewSegCount; int NxtSectnStartId = Bez.CtrlPts[newSectnIdx].SegStartIdx; //Insert Bezier Control Point Vector3 NewPos = Bez.Path[NewSectnSegStartId]; BezCtrlPt NewCtrlPt = new BezCtrlPt(Bez, NewPos); NewCtrlPt.BankAngle = BezCtrlPt.Current.BankAngle; Bez.CtrlPts.Insert(newSectnIdx, NewCtrlPt); Bez.SetCtrlPtIds(); //We dont have to move the path points from the old CtrlPt to the new one BezCtrlPt.Current.SegCount = CurrSectnNewSegCount; NewCtrlPt.SegCount = NewSectnSegCount; Bez.SetSegStartIds(); NewCtrlPt.CreateRoadMarker(); Bez.Interp(newSectnIdx - 1); Bez.Interp(newSectnIdx); Bez.Interp(newSectnIdx + 1); Bez.DrawLine(); Bez.AlignAllRoadMarkers(); //Insert Section iRoadSectn NewSectn = new RoadSectn(); NewSectn.Chargeable = false; NewSectn.Idx = newSectnIdx; NewSectn.LFenceType = CurrSectn.LFenceType; NewSectn.RFenceType = CurrSectn.RFenceType; NewSectn.SetMaterial(CurrSectn.Segments[0].roadMaterial); NewSectn.CreateGameObjects(); NewSectn.name = "RoadSection" + (newSectnIdx); NewSectn.goSectn.name = "RoadSection" + (newSectnIdx); Road.Instance.Sectns.Insert(newSectnIdx, NewSectn); // Section1 comes after RoadMarker1 Rd.OrganiseObjectsUsingBezierCtrlPtsAndPath(); /* * XSecCalculator.CalcXSecs(newSectnIdx-1, RoadWidth); * XSecCalculator.CalcXSecs(newSectnIdx, RoadWidth); * XSecCalculator.CalcXSecs(newSectnIdx+1, RoadWidth); * * CurrSectn.CalcFenceVerts(); * NewSectn.CalcFenceVerts(); * BuildQueue.Enqueue(newSectnIdx-1); * BuildQueue.Enqueue(newSectnIdx); */ }
public void Init() { //This is just because the sections and segments start at Idx=1 //Segment[0] doesn't do anything Segments.Clear(); XSecs.Clear(); Sectns.Clear(); //RacingLine = new RacingLine(); IsCircular = false; RoadSectn sectn = new RoadSectn(); Sectns.Add(sectn); sectn.Idx = 0; //Put all the materials in a dictionary for faster retrieval Material M; RoadMaterials = new Dictionary <string, Material>(); M = (Material)Resources.Load("Prefabs/Materials/Tarmac", typeof(Material)); RoadMaterials.Add("Tarmac", M); M = (Material)Resources.Load("Prefabs/Materials/Tarmac0", typeof(Material)); RoadMaterials.Add("Tarmac0", M); M = (Material)Resources.Load("Prefabs/Materials/Tarmac1", typeof(Material)); RoadMaterials.Add("Tarmac1", M); M = (Material)Resources.Load("Prefabs/Materials/Tarmac2", typeof(Material)); RoadMaterials.Add("Tarmac2", M); M = (Material)Resources.Load("Prefabs/Materials/Tarmac3", typeof(Material)); RoadMaterials.Add("Tarmac3", M); M = (Material)Resources.Load("Prefabs/Materials/Washboard0", typeof(Material)); RoadMaterials.Add("Washboard0", M); M = (Material)Resources.Load("Prefabs/Materials/Washboard1", typeof(Material)); RoadMaterials.Add("Washboard1", M); M = (Material)Resources.Load("Prefabs/Materials/DirtyRoad", typeof(Material)); RoadMaterials.Add("DirtyRoad", M); M = (Material)Resources.Load("Prefabs/Materials/DirtRoad0", typeof(Material)); RoadMaterials.Add("DirtRoad0", M); M = (Material)Resources.Load("Prefabs/Materials/DirtRoad1", typeof(Material)); RoadMaterials.Add("DirtRoad1", M); M = (Material)Resources.Load("Prefabs/Materials/DirtRoad2", typeof(Material)); RoadMaterials.Add("DirtRoad2", M); M = (Material)Resources.Load("Prefabs/Materials/DirtRoad3", typeof(Material)); RoadMaterials.Add("DirtRoad3", M); M = (Material)Resources.Load("Prefabs/Materials/TarmacUnderside", typeof(Material)); RoadMaterials.Add("TarmacUnderside", M); M = (Material)Resources.Load("Prefabs/Materials/WashboardUnderside", typeof(Material)); RoadMaterials.Add("WashboardUnderside", M); M = (Material)Resources.Load("Prefabs/Materials/DirtyRoadUnderside", typeof(Material)); RoadMaterials.Add("DirtyRoadUnderside", M); SkidMks = new Queue <FlatLineRenderer>(); }
public RoadSectn Decode() { RoadSectn rtn = new RoadSectn(); rtn.Idx = Idx; rtn.name = "RoadSection" + Idx; rtn.LFenceType = LFenceType; rtn.RFenceType = RFenceType; rtn.RoadMaterial = Mat; foreach (Vector3Serial VS in LFenceVerts) { rtn.LFenceVerts.Add(VS.V3); } foreach (Vector3Serial VS in RFenceVerts) { rtn.RFenceVerts.Add(VS.V3); } return(rtn); }
/// <summary> /// When you drop the marker onto the start marker /// It creates a smooth(ish) overlap by adding two extra control points /// and aligning them with points 2 and 3 /// </summary> /// <param name="Point"></param> public void JoinSection(Vector3 Point) { if (Rd.Sectns.Count < 4) { return; } int SegCount = Mathf.CeilToInt(Vector3.Distance(Point, Bez.CtrlPts[Bez.CtrlPts.Count - 2].Pos) / 0.84f); Road.Instance.IsCircular = true; RoadSectn Sectn = new RoadSectn(); int NewIdx = Road.Instance.Sectns.Count; Sectn.Idx = NewIdx; Sectn.name = "RoadSection" + (NewIdx); Rd.Sectns[NewIdx - 1].AddXSecs(SegCount); //Add XSecs to the PREVIOUS Section Sectn.CreateGameObjects(); Road.Instance.Sectns.Add(Sectn); //Move the hidden control point to the penultimate position: Bez.CtrlPts[0].Pos = Bez.CtrlPts[Bez.CtrlPts.Count - 2].Pos; //this doesnt work any more - had to fix it in CalcXSecs //Add a control point at the join Bez.AddControlPoint(Point, 0, SegCount); //We add a couple more control points so we can recalculate the curve after the join //We will remove one of these two in a sec RoadSectn OverlapSectn = new RoadSectn(); //OverlapSectn.AddXSecs(Rd.Sectns[1].Segments.Count); Bez.AddControlPoint(Bez.CtrlPts[2].Pos, Bez.CtrlPts[2].BankAngle, 20); Bez.AddControlPoint(Bez.CtrlPts[3].Pos, Bez.CtrlPts[3].BankAngle, 20); //Recalculate Section 1 that goes from CtrlPt1 to CtrlPt2 Bez.Interp(1); //It doesn't interp the Section before CtrlPt1 //Interp the path two before the end Bez.Interp(NewIdx - 1); //Interp the path just before the end Bez.Interp(NewIdx); Bez.AlignAllRoadMarkers(); XSecCalculator.CalcXSecs(2, RoadWidth); //Bez.RemoveLastControlPoint(); //Bez.CtrlPts[Bez.CtrlPts.Count - 1] = Bez.CtrlPts[Bez.CtrlPts.Count - 2]; XSecCalculator.CalcXSecs(NewIdx - 1, RoadWidth); XSecCalculator.CalcXSecs(NewIdx, RoadWidth); //NOt sure we need this next bit - We only need to calculate the XSec for one path point. // Commented out because it crashed - XSecCalculator.CalcXSecs(NewIdx + 1, RoadWidth); //Remove the 2 extra control points and their paths Bez.RemoveLastControlPoint(); Bez.RemoveLastControlPoint(); Bez.CtrlPts[Bez.CtrlPts.Count - 1].Pos = Bez.CtrlPts[2].Pos; //new bit for (int Idx = Bez.CtrlPts[NewIdx - 1].SegStartIdx; Idx < Bez.CtrlPts[NewIdx].SegStartIdx; Idx++) //create the segs ahead of the marker but don't mesh them { RoadSegment seg = new RoadSegment(); seg.Idx = Idx; seg.SectnIdx = NewIdx - 1; Rd.Sectns[NewIdx - 1].Segments.Add(seg); seg.CreateGameObjects(); seg.goSeg.name = "RoadSeg" + Idx; Rd.Segments.Add(seg); seg.SetMaterial(RoadMat); seg.LFenceType = LFenceType; seg.RFenceType = RFenceType; seg.goSeg.transform.SetParent(Rd.Sectns[NewIdx - 1].goSectn.transform); } Rd.Sectns[NewIdx - 1].SetMaterial(RoadMat); //bugfix 6/2/18 cos we now store RdMat in the section not the segment Rd.Sectns[NewIdx - 1].LFenceType = LFenceType; //Longstanding bug fixed Rd.Sectns[NewIdx - 1].RFenceType = RFenceType; //Longstanding bug fixed XSecCalculator.AdjustHairpin(Bez, NewIdx - 2); XSecCalculator.AdjustHairpin(Bez, NewIdx - 1); XSecCalculator.AdjustHairpin(Bez, 2); Road.Instance.Sectns[NewIdx - 3].CalcVisibleFenceVerts(); BuildQueue.Enqueue(NewIdx - 3); Road.Instance.Sectns[NewIdx - 2].CalcVisibleFenceVerts(); BuildQueue.Enqueue(NewIdx - 2); Road.Instance.Sectns[NewIdx - 1].CalcVisibleFenceVerts(); BuildQueue.Enqueue(NewIdx - 1); Road.Instance.Sectns[NewIdx].CalcVisibleFenceVerts(); //Join the beginning of the first Segment to the end of the last //Road.Instance.XSecs[0].KerbL = Road.Instance.XSecs[(Road.Instance.Sectns.Count - 2) * 20].KerbL; //Road.Instance.XSecs[0].KerbR = Road.Instance.XSecs[(Road.Instance.Sectns.Count - 2) * 20].KerbR; Road.Instance.Sectns[1].CalcVisibleFenceVerts(); BuildQueue.Enqueue(1); //Remove the Path points that were created when we added the second extra control point (The first one is needed because the SegVerts calculation needs it) //Bez.Path.RemoveRange(Bez.Path.Count - 20, 20); //This line commentd out now because RemoveCtrlPt also removes the Path Points Bez.DrawLine(); }
public void AddSection(Vector3 Point) //We add the section but we can't say how many segments it has //So we add the Xsecs and Segs for the previous section { if (Road.Instance.IsCircular) { return; } if (Bez.CtrlPts.Count > 3 && Vector3.Distance(Point, Bez.CtrlPts[Bez.CtrlPts.Count - 2].Pos) > 80) { Tut.gameObject.SetActive(true); Tut.ShowSpeech("This cone is too far from the last", 5); return; } int NewIdx = Road.Instance.Sectns.Count; int SegCount; Point = Bez.LimitSlope(Point, 0.33f); if (Bez.CtrlPts.Count == 2) { SegCount = 0; } else { SegCount = Mathf.CeilToInt(Vector3.Distance(Point, Bez.CtrlPts[Bez.CtrlPts.Count - 2].Pos) / 0.84f); } Bez.AddControlPoint(Point, 0, SegCount); Bez.Interp(NewIdx - 1); Bez.DrawLine(); RoadSectn Sectn = new RoadSectn(); Sectn.Idx = NewIdx; Sectn.name = "RoadSection" + (NewIdx); Rd.Sectns[NewIdx - 1].Chargeable = true; Rd.Sectns[NewIdx - 1].AddXSecs(SegCount); //Add XSecs to the PREVIOUS Section Sectn.CreateGameObjects(); Road.Instance.Sectns.Add(Sectn); // Section1 comes after RoadMarker1 Bez.CtrlPts[NewIdx].CreateRoadMarker(); Bez.AlignAllRoadMarkers(); XSecCalculator.CalcXSecs(NewIdx - 1, RoadWidth); //calculates for the section up to the previous marker for (int Idx = Bez.CtrlPts[NewIdx - 1].SegStartIdx; Idx < Bez.CtrlPts[NewIdx].SegStartIdx; Idx++) //create the segs ahead of the marker but don't mesh them { RoadSegment seg = new RoadSegment(); seg.Idx = Idx; seg.SectnIdx = NewIdx - 1; Rd.Sectns[NewIdx - 1].Segments.Add(seg); seg.CreateGameObjects(); seg.goSeg.name = "RoadSeg" + Idx; Rd.Segments.Add(seg); seg.SetMaterial(RoadMat); seg.LFenceType = LFenceType; seg.RFenceType = RFenceType; seg.goSeg.transform.SetParent(Rd.Sectns[NewIdx - 1].goSectn.transform); } Rd.Sectns[NewIdx].SetMaterial(RoadMat); Rd.Sectns[NewIdx - 1].LFenceType = LFenceType; Rd.Sectns[NewIdx - 1].RFenceType = RFenceType; Rd.Sectns[NewIdx - 1].SetMaterial(RoadMat); XSecCalculator.AdjustHairpin(Bez, NewIdx - 2); if (NewIdx > 3) { Road.Instance.Sectns[NewIdx - 3].CalcVisibleFenceVerts(); } BuildQueue.Enqueue(NewIdx - 3); Bez.CtrlPts[NewIdx].goRdMkr.GetComponent <RoadMarker>().Select(); //Update the tutorial if (SaveLoadModel.savedGames.Count < 3) { Tutorial Tut = _canvas.transform.Find("pnlTutorialBuild2(Clone)").GetComponent <Tutorial>(); int _roadCost = BillOfRoadMaterials.Items.Sum(i => i.Cost); int _sceneryCost = BillOfSceneryMaterials.Items.Sum(i => i.Opt.Cost); int conesLeft = (UserDataManager.Instance.Data.Coins - _roadCost - _sceneryCost) / 5; Tut.ShowSpeech(string.Format("You have money for {0:0.} more cones\n\nThe track must be a loop", conesLeft), 3); } }
public void Decode() { Road Rd = Road.Instance; Rd.Segments.Clear(); Rd.XSecs.Clear(); Rd.Sectns.Clear(); if (XSecs == null) { //in case we are loading a blank track Rd.Init(); } else { Rd.StartingLineSegIdx = StartingLineSegIdx; if (BuilderPos != null) { Rd.BuilderPos = BuilderPos.V3; } else { Rd.BuilderPos = new Vector3(0, 50f, 0); } if (BuilderRot != null) { Rd.BuilderRot = BuilderRot.Decode; } Rd.IsCircular = IsCircular; foreach (XSecSerial XS in XSecs) { XSec X = XS.Decode(); Rd.XSecs.Add(X); } foreach (RoadSectionSerial RSS in Sectns) { RoadSectn RS = RSS.Decode(); Rd.Sectns.Add(RS); } foreach (RoadSegmentSerial SegS in Segs) { RoadSegment Seg = SegS.Decode(); Rd.Segments.Add(Seg); } //Build the meshes for all the segments for (int Idx = 0; Idx < Segs.Length; Idx++) { RoadSegment seg = Road.Instance.Segments[Idx]; if (seg.HasMesh) { SegVerts Verts = XSecCalculator.SegmentVertices(Idx); seg.BuildMeshes(Verts); } //seg.GetTerrainHeights(); //seg.AdjustTerrain(); //seg.SetMaterial(); //seg.DeleteFence(); //seg.CreateFence(); } Rd.CalculateBends(); } }