예제 #1
0
    public void CreateRoofCollider()
    {
        if (XSecs.Count != 0)

        //  0 - 2 - 4 - 6 -...This section has 3 XSecs. 6 and 7 belong to the  next Sectn
        //  | \ | \ | \ |      so we'll only put a roof over the first 2
        //  1 - 3 - 5 - 7

        {
            Vector3[] RoofVerts = new Vector3[XSecs.Count * 2];
            int[]     RoofTris  = new int[XSecs.Count * 6 - 6];
            for (int i = 0; i < XSecs.Count() - 1; i++)
            {
                RoofVerts[i * 2]     = XSecs[i].TerrainL + Vector3.up * 2;
                RoofVerts[i * 2 + 1] = XSecs[i].TerrainR + Vector3.up * 2;
                RoofTris[i * 6]      = i * 2;
                RoofTris[i * 6 + 1]  = i * 2 + 1;
                RoofTris[i * 6 + 2]  = i * 2 + 3;
                RoofTris[i * 6 + 3]  = i * 2;
                RoofTris[i * 6 + 4]  = i * 2 + 3;
                RoofTris[i * 6 + 5]  = i * 2 + 2;
            }

            Mesh MR = new Mesh();
            MR.vertices  = RoofVerts;
            MR.triangles = RoofTris;
            MR.RecalculateBounds();
            MR.RecalculateNormals();
            ;
            GameObject goTempRoof = new GameObject();
            goTempRoof.name = "goTempRoof";
            goTempRoof.AddComponent <MeshCollider>().sharedMesh = MR;
        }
    }
예제 #2
0
 public void ListXSecs()
 {
     foreach (XSec x in XSecs)
     {
         Debug.Log("Index=" + XSecs.IndexOf(x) + " - " + x.Idx + x.MidPt);
     }
 }
예제 #3
0
    public void DeleteLastSectn()
    {
        //Actually we delete the penultimate section because the last section is empty
        if (Sectns.Count < 2)
        {
            return;
        }
        int        LastSectnId   = Sectns.Count - 1;
        int        PenultSectnId = Sectns.Count - 2;
        iRoadSectn LastSection   = Sectns.Last();
        iRoadSectn PenultSection = Sectns[Sectns.Count - 2];
        //iRoadSectn PrevSection = Sectns[Sectns.Count - 3];
        //int PrevSegCount = PrevSection.Segments.Count;
        int PenultSegCount   = PenultSection.Segments.Count;
        int PenultSegStartId = PenultSegCount > 0 ? PenultSection.Segments[0].Idx : 0;

        //I tested this function using Watches on all the XSecCounts, SegmentCounts and SegStart and SegCount for each section
        //comparing them before adding and deleting a section and then after

        //Remove Section's Segment GameObjects
        foreach (RoadSegment seg in PenultSection.Segments)
        {
            GameObject.Destroy(seg.goSeg);
        }

        if (!IsCircular)
        {
            Segments.RemoveRange(PenultSegStartId, PenultSegCount);
            PenultSection.Segments.Clear();
            PenultSection.DeleteFence();
            XSecs.RemoveRange(PenultSegStartId, PenultSegCount);
            //PenultSection.XSecs.Clear();
        }

        if (IsCircular)
        {
            PenultSection.DeleteFence();
            Segments.RemoveRange(PenultSegStartId, PenultSegCount);
            PenultSection.Segments.Clear();
            XSecs.RemoveRange(PenultSegStartId, PenultSegCount);
            //PenultSection.XSecs.Clear();
            //Road.Instance.XSecs.RemoveRange(PrevSegStartId, PrevSegCount);
        }

        //Delete Section
        GameObject.Destroy(LastSection.goSectn);
        Sectns.Remove(LastSection);

        BezierLine.Instance.RemoveLastControlPoint();  //also removes the path points and selects the previous CtrlPt
        IsCircular         = false;
        Game.current.Dirty = true;
    }
예제 #4
0
    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>();
    }
예제 #5
0
 private void PopulateXSecCurrBends()
 {
     foreach (Bend _bend in Bends)
     {
         //These two saved a massive performance hit
         Bend _nb = Bends.Next(_bend);
         for (XSec x = _bend.TurninXSec; x != _bend.ExitXSec; x = XSecs.Next(x))
         {
             x.CurrBend = _bend;
         }
         if (_nb.TurninXSec == null)
         {
             Debug.Log("BendId" + _bend.BendId + " no turnin");
         }
         else
         {
             for (XSec x = _bend.TurninXSec; x != _nb.TurninXSec; x = XSecs.Next(x))
             {
                 x.NextBend = _nb;
             }
         }
     }
 }
예제 #6
0
    public void CalculateBends()
    {
        if (!IsCircular)
        {
            return;
        }
        Bends = new CircleList <Bend>();
        Bend           _bend      = new Bend();
        int            BendId     = 0;
        MovingAvgFloat AngleQueue = new MovingAvgFloat(5);

        _bez = BezierLine.Instance;
        int      XSecCount = XSecs.Count();
        Vector3  PrevMid;
        Vector3  ThisMid;
        Vector3  NextMid;
        BendType _bt            = BendType.Unknown;
        BendType _prevbt        = BendType.Unknown;
        int      Incr           = 1;
        float    AngleThreshold = 1.34f;

        foreach (XSec X in XSecs)
        {
            PrevMid = XSecs.Prev(X).MidPt;
            ThisMid = X.MidPt;
            NextMid = XSecs.Next(X).MidPt;
            float Angle    = VectGeom.SignedAngle(ThisMid + ThisMid - PrevMid, ThisMid, NextMid, Vector3.up);
            float _segDist = Vector3.Distance(ThisMid, NextMid);
            AngleQueue.Push(Angle);
            if (Mathf.Abs(AngleQueue.Avg) < AngleThreshold)
            {
                _bt = BendType.Straight;
            }
            else
            {
                _bt = AngleQueue.Avg > 0 ? BendType.Right : BendType.Left;
            }

            if (_prevbt == _bt)
            {
                _bend.Angle += Angle;
            }
            else
            {
                if (_prevbt == BendType.Left || _prevbt == BendType.Right)
                {  //Finish off the previous bend
                    if (Mathf.Abs(_bend.Angle) < 15)
                    {
                        //ignore small bends
                        Bends.Remove(_bend);
                        BendId--;
                    }
                    else
                    {
                        //take 2 off cos of moving avg
                        _bend.EndXSec    = XSecs[X.Idx - 2];
                        _bend.EndSegIdx  = _bend.EndXSec.Idx;
                        _bend.ApexXSec   = XSecs[_bend.StartSegIdx + Mathf.RoundToInt(XSecs.Diff(_bend.StartXSec, _bend.EndXSec) / 2)];
                        _bend.ApexSegIdx = _bend.ApexXSec.Idx;
                        if (_bend.Type == BendType.Right)
                        {
                            _bend.ApexPos = _bend.ApexXSec.KerbR + (_bend.ApexXSec.KerbL - _bend.ApexXSec.KerbR).normalized; _bend.MinTurninPos = _bend.StartXSec.KerbR + (_bend.StartXSec.KerbL - _bend.StartXSec.KerbR).normalized * (_bend.Concatenated ? 4 : 2);
                        }
                        if (_bend.Type == BendType.Left)
                        {
                            _bend.ApexPos = _bend.ApexXSec.KerbL + (_bend.ApexXSec.KerbR - _bend.ApexXSec.KerbL).normalized; _bend.MinTurninPos = _bend.StartXSec.KerbL + (_bend.StartXSec.KerbR - _bend.StartXSec.KerbL).normalized * (_bend.Concatenated ? 4 : 2);
                        }
                        //Fmax = mv^2/r
                        float c = (_bend.EndSegIdx - _bend.StartSegIdx) * 360 / _bend.Angle;
                        float r = Mathf.Abs(c) / Mathf.PI / 2f;
                        //Debug.Log("Bend" + _bend.BendId + " radius = " + r);
                        _bend.SqrtRad = Mathf.Sqrt(r);
                    }
                }
                else
                {   //We might be starting a new bend or carrying n the previous one
                    if (_bt == BendType.Left || _bt == BendType.Right)
                    {
                        bool StartNewBend = true;

                        if (BendId > 0 && X.Idx - Bends[BendId - 1].EndSegIdx < 15 && Bends[BendId - 1].Type == _bt) ///bugbugbug circle bug
                        {                                                                                            //if the bend we've just finished is close to and the same sign as one before
                          //We just carry on with this bend and dont create a new one
                            StartNewBend       = false;
                            _bend.Concatenated = true;
                            GameObject.Destroy(GameObject.Find("Turnin" + _bend.BendId));
                            GameObject.Destroy(GameObject.Find("Apex" + _bend.BendId));
                            GameObject.Destroy(GameObject.Find("BendStart" + _bend.BendId));
                        }

                        if (StartNewBend)
                        {
                            //Create a new Bend
                            _bend             = new Bend();
                            _bend.Type        = _bt;
                            _bend.Sign        = _bt == BendType.Right ? (Int16)1 : (Int16)(-1);
                            _bend.StartXSec   = XSecs[X.Idx - 2];//-2 cos of moving avg
                            _bend.StartSegIdx = _bend.StartXSec.Idx;
                            _bend.Angle       = Angle;
                            _bend.BendId      = BendId;
                            Bends.Add(_bend);
                            BendId++;
                        }
                    }
                }
                //******************************************************************************************
            }
            _prevbt = _bt;
        }
        //This is the last bend. NOt a brilliant bit but it doesn't crash
        if (_bt == BendType.Straight)
        {
            goto Finalise;
        }
        _bend.EndSegIdx = XSecs.Count - 1;
        _bend.EndXSec   = XSecs[_bend.EndSegIdx];
        if (_bend.EndSegIdx <= _bend.StartSegIdx && Bends.Count() > 0)
        {
            Bends.Remove(_bend); Bends.Last().EndSegIdx = XSecs.Count;
        }
        else
        {
            _bend.ApexSegIdx = Mathf.RoundToInt((_bend.EndSegIdx + _bend.StartSegIdx) / 2);
            _bend.ApexXSec   = XSecs[_bend.ApexSegIdx];
            if (_bend.Type == BendType.Right)
            {
                _bend.ApexPos = _bend.ApexXSec.KerbR + (_bend.ApexXSec.KerbL - _bend.ApexXSec.KerbR).normalized;
            }
            if (_bend.Type == BendType.Left)
            {
                _bend.ApexPos = _bend.ApexXSec.KerbL + (_bend.ApexXSec.KerbR - _bend.ApexXSec.KerbL).normalized;
            }
        }
Finalise:
        CalculateTurninAndExitPoints();
        PopulateXSecCurrBends();
    }