private static void ProcessRoad_Terrain_Hook1_Do(ref GSDSplineC tSpline,ref GSDRoad tRoad, bool bMultithreaded){ if(tRoad.bProfiling){ Profiler.BeginSample("ProcessRoad_Terrain_Hook1_Do"); } //First lets make sure all terrains have GSD shit on them: CheckAllTerrains(); //Reset the terrain: if(tRoad.bProfiling){ Profiler.BeginSample("TerrainsReset"); } GSDTerraforming.TerrainsReset(tRoad); if(tRoad.bProfiling){ Profiler.EndSample(); } float heightDistance = tRoad.opt_MatchHeightsDistance; // float treeDistance = tRoad.opt_ClearTreesDistance; float detailDistance = tRoad.opt_ClearDetailsDistance; Dictionary<Terrain,TempTerrainData> TempTerrainDict = new Dictionary<Terrain, TempTerrainData>(); //Populate dictionary: Object[] tTerrains = GameObject.FindObjectsOfType(typeof(Terrain)); GSDTerrain TID; int aSize = 0; int dSize = 0; TempTerrainData TTD; bool bContains = false; GSDRoadUtil.Construction2DRect tRect = null; // GSDRoadUtil.Construction2DRect rRect = null; foreach(Terrain tTerrain in tTerrains){ tRect = GetTerrainBounds(tTerrain); bContains = false; //Debug.Log(tTerrain.transform.name + " bounds: " + tRect.ToStringGSD()); //Debug.Log(" Road bounds: " + tSpline.RoadV0 + "," + tSpline.RoadV1 + "," + tSpline.RoadV2 + "," + tSpline.RoadV3); if (bContains != true && tRect.Contains(ref tSpline.RoadV0)) { bContains = true; } else if (bContains != true && tRect.Contains(ref tSpline.RoadV1)) { bContains = true; } else if (bContains != true && tRect.Contains(ref tSpline.RoadV2)) { bContains = true; } else if (bContains != true && tRect.Contains(ref tSpline.RoadV3)) { bContains = true; } else { int mCount3 = tRoad.GSDSpline.GetNodeCount(); Vector2 tVect2D_321 = default(Vector2); for (int i = 0; i < mCount3; i++) { tVect2D_321 = new Vector2(tRoad.GSDSpline.mNodes[i].pos.x, tRoad.GSDSpline.mNodes[i].pos.z); if (tRect.Contains(ref tVect2D_321)) { bContains = true; break; } } if (!bContains) { float tDef = 5f / tSpline.distance; Vector2 x2D = default(Vector2); Vector3 x3D = default(Vector3); for (float i = 0f; i <= 1f; i += tDef) { x3D = tSpline.GetSplineValue(i); x2D = new Vector2(x3D.x, x3D.z); if (tRect.Contains(ref x2D)) { bContains = true; break; } } } } // rRect = new GSD.Roads.GSDRoadUtil.Construction2DRect(tSpline.RoadV0,tSpline.RoadV1,tSpline.RoadV2,tSpline.RoadV3); if(bContains && !TempTerrainDict.ContainsKey(tTerrain)){ TTD = new TempTerrainData(); TTD.HM = tTerrain.terrainData.heightmapResolution; TTD.HMHeight = tTerrain.terrainData.heightmapHeight; TTD.heights = tTerrain.terrainData.GetHeights(0,0,tTerrain.terrainData.heightmapWidth,tTerrain.terrainData.heightmapHeight); TTD.HMRatio = TTD.HM / tTerrain.terrainData.size.x; TTD.MetersPerHM = tTerrain.terrainData.size.x / tTerrain.terrainData.heightmapResolution; float DetailRatio = tTerrain.terrainData.detailResolution / tTerrain.terrainData.size.x; //Heights: if(tRoad.bProfiling){ Profiler.BeginSample("Heights"); } if(tRoad.opt_HeightModEnabled){ aSize = (int)tSpline.distance * ((int)(heightDistance*1.65f*TTD.HMRatio)+2); if(aSize > (tTerrain.terrainData.heightmapResolution * tTerrain.terrainData.heightmapResolution)){ aSize = tTerrain.terrainData.heightmapResolution * tTerrain.terrainData.heightmapResolution; } TTD.cX = new ushort[aSize]; TTD.cY = new ushort[aSize]; TTD.oldH = new float[aSize]; TTD.cH = new float[aSize]; TTD.cI = 0; TTD.TerrainMaxIndex = tTerrain.terrainData.heightmapResolution; TTD.TerrainSize = tTerrain.terrainData.size; TTD.TerrainPos = tTerrain.transform.position; TTD.tHeights = new bool[tTerrain.terrainData.heightmapWidth,tTerrain.terrainData.heightmapHeight]; TID = tTerrain.transform.gameObject.GetComponent<GSDTerrain>(); if(TID != null){ TTD.GSDID = TID.GSDID; TempTerrainDict.Add(tTerrain,TTD); } } if(tRoad.bProfiling){ Profiler.EndSample(); } //Details: if(tRoad.bProfiling){ Profiler.BeginSample("Details"); } if(tRoad.opt_DetailModEnabled){ // TTD.DetailValues = new Dictionary<int, int[,]>(); TTD.DetailLayersCount = tTerrain.terrainData.detailPrototypes.Length; // TTD.DetailHasProcessed = new Dictionary<int, bool[,]>(); TTD.DetailHasProcessed = new HashSet<int>(); TTD.MainDetailsX = new List<ushort>(); TTD.MainDetailsY = new List<ushort>(); TTD.DetailsI = new int[TTD.DetailLayersCount]; TTD.DetailToHeightRatio = (float)((float)tTerrain.terrainData.detailResolution) / ((float)tTerrain.terrainData.heightmapResolution); TTD.DetailMaxIndex = tTerrain.terrainData.detailResolution; TTD.DetailLayersSkip = new HashSet<int>(); // Get all of layer zero. // int[] mMinMaxDetailEntryCount = new int[TTD.DetailLayersCount]; // if(tRoad.bProfiling){ Profiler.BeginSample("DetailValues"); } // Vector3 bVect = default(Vector3); // Vector2 bVect2D = default(Vector2); // int DetailRes = tTerrain.terrainData.detailResolution; // for(int i=0;i<TTD.DetailLayersCount;i++){ // int[,] tInts = tTerrain.terrainData.GetDetailLayer(0,0,tTerrain.terrainData.detailWidth,tTerrain.terrainData.detailHeight,i); // int Length1 = tInts.GetLength(0); // int Length2 = tInts.GetLength(1); // for (int y=0;y < Length1;y++){ // for (int x=0;x < Length2;x++){ // if(tInts[x,y] > 0){ // bVect = new Vector3(((float)y/(float)DetailRes) * TTD.TerrainSize.x,0f,((float)x/(float)DetailRes) * TTD.TerrainSize.z); // bVect = tTerrain.transform.TransformPoint(bVect); // bVect2D = new Vector2(bVect.z,bVect.x); // if(rRect.Contains(ref bVect2D)){ // mMinMaxDetailEntryCount[i] += 1; // } // } // } // } // if(mMinMaxDetailEntryCount[i] < 1){ // TTD.DetailLayersSkip.Add(i); // tInts = null; // }else{ // TTD.DetailValues.Add(i,tInts); // TTD.DetailHasProcessed.Add(i,new bool[tTerrain.terrainData.detailWidth,tTerrain.terrainData.detailHeight]); // } // } // if(tRoad.bProfiling){ Profiler.EndSample(); } dSize = (int)tSpline.distance * ((int)(detailDistance*3f*DetailRatio)+2); if(dSize > (tTerrain.terrainData.detailResolution * tTerrain.terrainData.detailResolution)){ dSize = tTerrain.terrainData.detailResolution * tTerrain.terrainData.detailResolution; } // TTD.DetailsX = new List<ushort[]>(); // TTD.DetailsY = new List<ushort[]>(); // TTD.OldDetailsValue = new List<ushort[]>(); TTD.DetailsX = new List<List<ushort>>(); TTD.DetailsY = new List<List<ushort>>(); TTD.OldDetailsValue = new List<List<ushort>>(); // TTD.DetailHasProcessed = new List<List<bool>>(); for(int i=0;i<TTD.DetailLayersCount;i++){ // if(TTD.DetailLayersSkip.Contains(i)){ // TTD.DetailsX.Add(new ushort[0]); // TTD.DetailsY.Add(new ushort[0]); // TTD.OldDetailsValue.Add(new ushort[0]); // continue; // } // int detailentrycount = (int)((float)mMinMaxDetailEntryCount[i] * 1.5f); // int d_temp_Size = dSize; // if(d_temp_Size > detailentrycount){ d_temp_Size = detailentrycount; } // if(d_temp_Size < 1){ d_temp_Size = 1; } // if(d_temp_Size > (tTerrain.terrainData.detailResolution * tTerrain.terrainData.detailResolution)){ // d_temp_Size = tTerrain.terrainData.detailResolution * tTerrain.terrainData.detailResolution; // } // // TTD.DetailsX.Add(new ushort[d_temp_Size]); // TTD.DetailsY.Add(new ushort[d_temp_Size]); // TTD.OldDetailsValue.Add(new ushort[d_temp_Size]); TTD.DetailsX.Add(new List<ushort>()); TTD.DetailsY.Add(new List<ushort>()); TTD.OldDetailsValue.Add(new List<ushort>()); } // TTD.DetailsX = new ushort[TTD.DetailLayersCount,dSize]; // TTD.DetailsY = new ushort[TTD.DetailLayersCount,dSize]; // TTD.OldDetailsValue = new ushort[TTD.DetailLayersCount,dSize]; } if(tRoad.bProfiling){ Profiler.EndSample(); } //Trees: if(tRoad.bProfiling){ Profiler.BeginSample("Trees"); } if(tRoad.opt_TreeModEnabled){ // TTD.TreesCurrent = tTerrain.terrainData.treeInstances; TTD.TreesCurrent = new List<TreeInstance>(tTerrain.terrainData.treeInstances); TTD.TreeSize = TTD.TreesCurrent.Count; TTD.TreesI = 0; TTD.TreesOld = new List<TreeInstance>(); } if(tRoad.bProfiling){ Profiler.EndSample(); } } } //Figure out relevant TTD to spline: List<TempTerrainData> EditorTTDList = new List<TempTerrainData>(); if(TempTerrainDict != null){ foreach(Terrain tTerrain in tTerrains){ if(TempTerrainDict.ContainsKey(tTerrain)){ EditorTTDList.Add(TempTerrainDict[tTerrain]); } } } if(tRoad.bProfiling){ Profiler.EndSample(); } //Start job now, for each relevant TTD: tRoad.EditorTerrainCalcs(ref EditorTTDList); if(bMultithreaded){ GSD.Threaded.TerrainCalcs tJob = new GSD.Threaded.TerrainCalcs(); tJob.Setup(ref EditorTTDList,tSpline,tRoad); tRoad.TerrainCalcsJob = tJob; tJob.Start(); }else{ GSD.Threaded.TerrainCalcs_Static.RunMe(ref EditorTTDList,tSpline,tRoad); } }