private static void DoRectsDo(ref GSDSplineC tSpline,ref GSD.Roads.GSDTerraforming.TempTerrainData TTD)
        {
            float Sep = tSpline.tRoad.RoadWidth()*0.5f;
            float HeightSep = Sep + (tSpline.tRoad.opt_MatchHeightsDistance * 0.5f);
            List<TerrainBoundsMaker> TBMList = new List<TerrainBoundsMaker>();
            //			List<GSD.Roads.GSDRoadUtil.Construction3DTri> triList = new List<GSD.Roads.GSDRoadUtil.Construction3DTri>();
            List<GSD.Roads.GSDRoadUtil.Construction2DRect> TreerectList = new List<GSD.Roads.GSDRoadUtil.Construction2DRect>();
            float tStep = tSpline.tRoad.opt_RoadDefinition / tSpline.distance;
            //			tStep *= 0.5f;

            //Start initializing the loop. Convuluted to handle special control nodes, so roads don't get rendered where they aren't supposed to, while still preserving the proper curvature.
            float FinalMax = 1f;
            float StartMin = 0f;
            if(tSpline.bSpecialEndControlNode){	//If control node, start after the control node:
                FinalMax = tSpline.mNodes[tSpline.GetNodeCount()-2].tTime;
            }
            if(tSpline.bSpecialStartControlNode){	//If ends in control node, end construction before the control node:
                StartMin = tSpline.mNodes[1].tTime;
            }
            //			bool bFinalEnd = false;
            //			float RoadConnection_StartMin1 = StartMin;	//Storage of incremental start values for the road connection mesh construction at the end of this function.
            //			float RoadConnection_FinalMax1 = FinalMax; 	//Storage of incremental end values for the road connection mesh construction at the end of this function.
            if(tSpline.bSpecialEndNode_IsStart_Delay){
                StartMin += (tSpline.SpecialEndNodeDelay_Start / tSpline.distance);	//If there's a start delay (in meters), delay the start of road construction: Due to special control nodes for road connections or 3 way intersections.
            }else if(tSpline.bSpecialEndNode_IsEnd_Delay){
                FinalMax -= (tSpline.SpecialEndNodeDelay_End / tSpline.distance);	//If there's a end delay (in meters), cut early the end of road construction: Due to special control nodes for road connections or 3 way intersections.
            }
            //			float RoadConnection_StartMin2 = StartMin;	//Storage of incremental start values for the road connection mesh construction at the end of this function.
            //			float RoadConnection_FinalMax2 = FinalMax; 	//Storage of incremental end values for the road connection mesh construction at the end of this function.

            FinalMax = FinalMax + tStep;

            Vector3 tVect1 = default(Vector3);
            Vector3 tVect2 = default(Vector3);
            Vector3 POS1 = default(Vector3);
            Vector3 POS2 = default(Vector3);
            if(FinalMax > 1f){ FinalMax = 1f; }

            float tNext = 0f;
            float fValue1,fValue2;
            float fValueMod = tSpline.tRoad.opt_RoadDefinition / tSpline.distance;
            bool bIsPastInter = false;
            float tIntStrength = 0f;
            float tIntStrength2 = 0f;
            //			bool bMaxIntersection = false;
            //			bool bFirstInterNode = false;
            GSDSplineN xNode = null;
            float tIntHeight = 0f;
            float tIntHeight2 = 0f;
            GSDRoadIntersection GSDRI = null;
            float T1SUB = 0f;
            float T2SUB = 0f;
            bool bIntStr1_Full = false;
            bool bIntStr1_FullPrev = false;
            bool bIntStr1_FullNext = false;
            bool bIntStr2_Full = false;
            bool bIntStr2_FullPrev = false;
            bool bIntStr2_FullNext = false;
            Vector3 tVect3 = default(Vector3);
            //			bool bStarted = false;
            //			bool T3Added = false;
            List<int[]> tXYs = new List<int[]>();
            float TreeClearDist = tSpline.tRoad.opt_ClearTreesDistance;
            if(TreeClearDist < tSpline.tRoad.RoadWidth()){ TreeClearDist = tSpline.tRoad.RoadWidth(); }
            GSD.Roads.GSDRoadUtil.Construction2DRect tRect = null;
            float tGrade = 0f;
            for(float i=StartMin;i<FinalMax;i+=tStep){
                if(tSpline.tRoad.opt_HeightModEnabled){
                    if(i > 1f){ break; }
                    tNext = i+tStep;
                    if(tNext > 1f){ break; }

                    tSpline.GetSplineValue_Both(i,out tVect1,out POS1);

                    if(tNext <= 1f){
                        tSpline.GetSplineValue_Both(tNext,out tVect2,out POS2);
                    }else{
                        tSpline.GetSplineValue_Both(1f,out tVect2,out POS2);
                    }

                    //Determine if intersection:
                    bIsPastInter = false;	//If past intersection
                    tIntStrength = tSpline.IntersectionStrength(ref tVect1,ref tIntHeight, ref GSDRI, ref bIsPastInter, ref i, ref xNode);
            //					if(IsApproximately(tIntStrength,1f,0.001f) || tIntStrength > 1f){
            //						bMaxIntersection = true;
            //					}else{
            //						bMaxIntersection = false;
            //					}
            //					bFirstInterNode = false;

                    tIntStrength2 = tSpline.IntersectionStrength(ref tVect2,ref tIntHeight2, ref GSDRI, ref bIsPastInter, ref i, ref xNode);
                    if(tIntStrength2 > 1f){ tIntStrength2 = 1f; }

                    T1SUB = tVect1.y;
                    T2SUB = tVect2.y;

                    if(tIntStrength > 1f){ tIntStrength = 1f; }
                    if(tIntStrength >= 0f){// || IsApproximately(tIntStrength,0f,0.01f)){
                        if(IsApproximately(tIntStrength,1f,0.01f)){
                            T1SUB = tIntHeight;
                            bIntStr1_Full = true;
                            bIntStr1_FullNext = false;
                        }else{
                         	bIntStr1_Full = false;
                            bIntStr1_FullNext = (tIntStrength2 >= 1f);
                            if(!IsApproximately(tIntStrength,0f,0.01f)){ T1SUB = (tIntStrength*tIntHeight) + ((1-tIntStrength)*tVect1.y); }
            //						if(tIntStrength <= 0f){ T1SUB = (tIntStrength*tIntHeight) + ((1-tIntStrength)*tVect1.y); }
                        }

                        if((bIntStr1_Full && !bIntStr1_FullPrev) || (!bIntStr1_Full && bIntStr1_FullNext)){
                            tGrade = tSpline.GetCurrentNode(i).GradeToPrevValue;
                            if(tGrade < 0f){
                                T1SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,(tGrade/20f)*-1f);
                            }else{
                                T1SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,tGrade/20f);
                            }

            //							if(tGrade < 0f){
            //								T1SUB *= -1f;
            //							}
                        }else if(bIntStr1_Full && !bIntStr1_FullNext){
                            tGrade = tSpline.GetCurrentNode(i).GradeToNextValue;
                            if(tGrade < 0f){
                                T1SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,(tGrade/20f)*-1f);
                            }else{
                                T1SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,tGrade/20f);
                            }
            //							if(tGrade < 0f){
            //								T1SUB *= -1f;
            //							}
                        }else{
                            T1SUB -= 0.02f;
                        }
                        bIntStr1_FullPrev = bIntStr1_Full;
                    }

                    if(tIntStrength2 >= 0f || IsApproximately(tIntStrength2,0f,0.01f)){
            //					if(!IsApproximately(tIntStrength,1f,0.01f)){
                        if(IsApproximately(tIntStrength,1f,0.01f)){
                            bIntStr2_Full = true;
                            T2SUB = tIntHeight2;
                        }else{
                         	bIntStr2_Full = false;
                            if(!IsApproximately(tIntStrength2,0f,0.01f)){ T2SUB = (tIntStrength2*tIntHeight) + ((1-tIntStrength2)*tVect2.y); }
            //						if(tIntStrength2 <= 0f){ T2SUB = (tIntStrength2*tIntHeight) + ((1-tIntStrength2)*tVect2.y); }
                        }

                        if((bIntStr2_Full && !bIntStr2_FullPrev)){
                            tGrade = tSpline.GetCurrentNode(i).GradeToPrevValue;
                            if(tGrade < 0f){
                                T2SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,(tGrade/20f)*-1f);
                            }else{
                                T2SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,tGrade/20f);
                            }
            //							T2SUB -= tIntHeight2 - tVect2.y;
                        }else if(bIntStr2_Full && !bIntStr2_FullNext){
                            tGrade = tSpline.GetCurrentNode(i).GradeToNextValue;
                            if(tGrade < 0f){
                                T2SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,(tGrade/20f)*-1f);
                            }else{
                                T2SUB -= Mathf.Lerp(0.02f,GSDRI.GradeMod,tGrade/20f);
                            }
            //							if(tGrade < 0f){
            //								T2SUB *= -1f;
            //							}
            //							T2SUB -= tIntHeight2 - tVect2.y;
                        }else if(!bIntStr2_Full){
                            if(tNext+tStep < 1f){
                                tVect3 = tSpline.GetSplineValue(tNext+tStep,false);
                                tIntStrength2 = tSpline.IntersectionStrength(ref tVect3,ref tIntHeight2, ref GSDRI, ref bIsPastInter, ref i, ref xNode);
                            }else{
                                tIntStrength2 = 0f;
                            }

                            if(tIntStrength2 >= 1f){
                                T2SUB -= 0.06f;
                            }else{
                                T2SUB -= 0.02f;
                            }
                        }else{
                            T2SUB -= 0.02f;
                        }
                        bIntStr2_FullPrev = bIntStr2_Full;
                    }

                    fValue1=i - fValueMod;
                    fValue2=i + fValueMod;
                    if(fValue1 < 0){ fValue1 = 0; }
                    if(fValue2 > 1){ fValue2 = 1; }

                    tXYs.Add(CreateTris(fValue1,fValue2,ref tVect1,ref POS1,ref tVect2,ref POS2,Sep,ref TBMList,ref T1SUB, ref T2SUB, ref TTD, HeightSep));

                    //Details and trees:
                    tRect = SetDetailCoords(i,ref tVect1,ref POS1,ref tVect2, ref POS2,tSpline.tRoad.opt_ClearDetailsDistance,TreeClearDist, ref TTD, ref tSpline);
                    if(tSpline.tRoad.opt_TreeModEnabled && tRect != null){
                        TreerectList.Add(tRect);
                    }
                }else{
                    if(i > 1f){ break; }
                    tNext = i+tStep;
                    if(tNext > 1f){ break; }

                    tSpline.GetSplineValue_Both(i,out tVect1,out POS1);

                    if(tNext <= 1f){
                        tSpline.GetSplineValue_Both(tNext,out tVect2,out POS2);
                    }else{
                        tSpline.GetSplineValue_Both(1f,out tVect2,out POS2);
                    }

                    //Details and trees:
                    tRect = SetDetailCoords(i,ref tVect1,ref POS1,ref tVect2, ref POS2,tSpline.tRoad.opt_ClearDetailsDistance,TreeClearDist, ref TTD, ref tSpline);
                    if(tSpline.tRoad.opt_TreeModEnabled && tRect != null){
                        TreerectList.Add(tRect);
                    }
                }
            }

            if(tSpline.tRoad.bProfiling){
                Profiler.BeginSample("DoRectsTree");
            }
            if(tSpline.tRoad.opt_TreeModEnabled && TreerectList != null && TreerectList.Count > 0){
                int tCount = TTD.TreeSize;
                int jCount = TreerectList.Count;
                Vector3 tVect3D = default(Vector3);
                Vector2 tVect2D = default(Vector2);
                TreeInstance tTree;
                for(int i=0;i<tCount;i++){
                    tTree = TTD.TreesCurrent[i];

                    tVect3D = tTree.position;
                    tVect3D.x *= TTD.TerrainSize.z;
                    tVect3D.y *= TTD.TerrainSize.y;
                    tVect3D.z *= TTD.TerrainSize.x;
                    tVect3D += TTD.TerrainPos;
                    tVect2D.x = tVect3D.x;
                    tVect2D.y = tVect3D.z;

                    for(int j=0;j<jCount;j++){
                        if(TreerectList[j].Contains(ref tVect2D)){
                            TTD.TreesOld.Add(TTD.TreesCurrent[i]);
                            tTree = TTD.TreesCurrent[i];
                            tTree.prototypeIndex = -2;
                            TTD.TreesCurrent[i] = tTree;
                            TTD.TreesI+=1;
                            break;
                        }
                    }
                }
                TTD.TreesCurrent.RemoveAll(item => item.prototypeIndex < -1);
            }
            if(tSpline.tRoad.bProfiling){
                Profiler.EndSample();
            }

            if(!tSpline.tRoad.opt_HeightModEnabled){
                return;
            }

            //			//Temp testing:
            //			tSpline.mNodes[22].tTriList = new List<GSD.Roads.GSDRoadUtil.Construction3DTri>();
            //			int tCount = triList.Count;
            //			for(int i=0;i<tCount;i++){
            //				tSpline.mNodes[22].tTriList.Add(triList[i]);
            //			}
            //			tSpline.mNodes[22].tHMList = new List<Vector3>();

            float tFloat = -1f;
            Sep = tSpline.tRoad.RoadWidth()*1.5f;
            int k = 0;
            int[] tXY = null;
            int tXYsCount = tXYs.Count;
            bool bIsBridge = false;
            bool bIsTunnel = false;
            for(float i=StartMin;i<FinalMax;i+=tStep){
                if(TBMList.Count > 0){
                    if(TBMList[0].MaxI < i){
                        CleanupTris(i,ref TBMList);
                    }
                }else{
                    break;
                }

                //If in bridg mode:
                if(tSpline.IsInBridgeTerrain(i)){
                    bIsBridge = true;
                }else{
                    bIsBridge = false;
                }
                //If in tunnel mode:
                if(tSpline.IsInTunnelTerrain(i)){
                    bIsTunnel = true;
                }else{
                    bIsTunnel = false;
                }

                if(k < tXYsCount){
                    tXY = tXYs[k];
                    tFloat = ProcessCoordinateGrabber(ref i,ref tSpline,ref TTD, ref TBMList,ref tXY, bIsBridge, bIsTunnel);
                    if(!IsApproximately(tFloat,0f,0.0001f)){
                        tSpline.HeightHistory.Add(new KeyValuePair<float,float>(i,tFloat));
                    }
                }else{
                    break;
                }
                k+=1;
            }
        }
Ejemplo n.º 2
0
    public void EnsureGradeValidity(int iStart = -1, bool bIsAddToEnd = false)
    {
        if (GSDSpline == null)
        {
            return;
        }
        GSDSplineN PrevNode = null;
        GSDSplineN NextNode = null;

        if (bIsAddToEnd && GSDSpline.GetNodeCount() > 0)
        {
            PrevNode = GSDSpline.mNodes[GSDSpline.GetNodeCount() - 1];
        }
        else
        {
            if (iStart == -1)
            {
                PrevNode = GSDSpline.GetPrevLegitimateNode(idOnSpline);
            }
            else
            {
                PrevNode = GSDSpline.GetPrevLegitimateNode(iStart);
            }
        }
        if (PrevNode == null)
        {
            return;
        }
        Vector3 tVect = transform.position;

        float tMinY1 = 0f;
        float tMinY2 = 0f;
        float tMaxY1 = 0f;
        float tMaxY2 = 0f;

        if (PrevNode != null)
        {
            PrevNode.FilterMaxGradeHeight(tVect, out tMinY1, out tMaxY1);
        }
        if (NextNode != null)
        {
            NextNode.FilterMaxGradeHeight(tVect, out tMinY2, out tMaxY2);
        }

        bool bPrevNodeGood = false;
        bool bNextNodeGood = false;

        if (tVect.y > tMinY1 && tVect.y < tMaxY1)
        {
            bPrevNodeGood = true;
        }
        if (tVect.y > tMinY2 && tVect.y < tMaxY2)
        {
            bNextNodeGood = true;
        }

        if (!bPrevNodeGood && !bNextNodeGood && PrevNode != null && NextNode != null)
        {
            float tMaxY3 = Mathf.Min(tMaxY1, tMaxY2);
            float tMinY3 = Mathf.Max(tMinY1, tMinY2);
            if (tVect.y < tMinY3)
            {
                tVect.y = tMinY3;
            }
            else if (tVect.y > tMaxY3)
            {
                tVect.y = tMaxY3;
            }
        }
        else
        {
            if (!bPrevNodeGood && PrevNode != null)
            {
                if (tVect.y < tMinY1)
                {
                    tVect.y = tMinY1;
                }
                else if (tVect.y > tMaxY1)
                {
                    tVect.y = tMaxY1;
                }
            }
            else if (!bNextNodeGood && NextNode != null)
            {
                if (tVect.y < tMinY2)
                {
                    tVect.y = tMinY2;
                }
                else if (tVect.y > tMaxY2)
                {
                    tVect.y = tMaxY2;
                }
            }
        }

        transform.position = tVect;
    }