private static void ProcessDetails(Dictionary <int, int[, ]> details, Expression.DslCalculator calc, string proc, int cx, int cy, int r) { int x = cx - r; int y = cy - r; int w = r * 2; int h = r * 2; int r2 = r * r; for (int ix = 0; ix < w; ++ix) { for (int iy = 0; iy < h; ++iy) { int xi = x + ix; int yi = y + iy; int dx = xi - cx; int dy = yi - cy; if (dx * dx + dy * dy <= r2) { foreach (var pair in details) { int layer = pair.Key; var detail = pair.Value[xi, yi]; calc.NamedVariables["detail"] = detail; calc.Calc(proc, xi, yi, layer); pair.Value[xi, yi] = (int)Convert.ChangeType(calc.NamedVariables["detail"], typeof(int)); } } } } }
private static void ProcessAlphamaps(float[,,] alphamaps, Expression.DslCalculator calc, string proc, int cx, int cy, int r) { int alphanum = alphamaps.GetLength(2); int x = cx - r; int y = cy - r; int w = r * 2; int h = r * 2; int r2 = r * r; for (int ix = 0; ix < w; ++ix) { for (int iy = 0; iy < h; ++iy) { int xi = x + ix; int yi = y + iy; int dx = xi - cx; int dy = yi - cy; if (dx * dx + dy * dy <= r2) { float[] alphas = calc.NamedVariables["alphas"] as float[]; for (int i = 0; i < alphanum; ++i) { alphas[i] = alphamaps[xi, yi, i]; } var v = calc.Calc(proc, xi, yi); for (int i = 0; i < alphanum; ++i) { alphamaps[xi, yi, i] = alphas[i]; } } } } }
private static void ProcessHeights(float[,] datas, Expression.DslCalculator calc, string proc, int cx, int cy, int r) { int x = cx - r; int y = cy - r; int w = r * 2; int h = r * 2; int r2 = r * r; for (int ix = 0; ix < w; ++ix) { for (int iy = 0; iy < h; ++iy) { int xi = x + ix; int yi = y + iy; int dx = xi - cx; int dy = yi - cy; if (dx * dx + dy * dy <= r2) { calc.NamedVariables["height"] = datas[yi, xi]; calc.Calc(proc, xi, yi); datas[yi, xi] = (float)Convert.ChangeType(calc.NamedVariables["height"], typeof(float)); } } } }
private static void ProcessHeights(float[,] datas, Expression.DslCalculator calc, string proc, int x, int y, int w, int h) { for (int ix = 0; ix < w; ++ix) { for (int iy = 0; iy < h; ++iy) { int xi = x + ix; int yi = y + iy; calc.NamedVariables["height"] = datas[yi, xi]; calc.Calc(proc, xi, yi); datas[yi, xi] = (float)Convert.ChangeType(calc.NamedVariables["height"], typeof(float)); } } }
private static void ProcessDetails(Dictionary <int, int[, ]> details, Expression.DslCalculator calc, string proc, int x, int y, int w, int h) { for (int ix = 0; ix < w; ++ix) { for (int iy = 0; iy < h; ++iy) { int xi = x + ix; int yi = y + iy; foreach (var pair in details) { int layer = pair.Key; var detail = pair.Value[xi, yi]; calc.NamedVariables["detail"] = detail; calc.Calc(proc, xi, yi, layer); pair.Value[xi, yi] = (int)Convert.ChangeType(calc.NamedVariables["detail"], typeof(int)); } } } }
private static void ProcessAlphamaps(float[,,] alphamaps, Expression.DslCalculator calc, string proc, int x, int y, int w, int h) { int alphanum = alphamaps.GetLength(2); for (int ix = 0; ix < w; ++ix) { for (int iy = 0; iy < h; ++iy) { int xi = x + ix; int yi = y + iy; float[] alphas = calc.NamedVariables["alphas"] as float[]; for (int i = 0; i < alphanum; ++i) { alphas[i] = alphamaps[xi, yi, i]; } var v = calc.Calc(proc, xi, yi); for (int i = 0; i < alphanum; ++i) { alphamaps[xi, yi, i] = alphas[i]; } } } }
private static void ProcessWithDsl(Dsl.FunctionData funcData, string type, float[,] datas, float[, ,] alphamaps, Dictionary <int, int[, ]> details, Expression.DslCalculator calc, string proc, ref bool resetTrees) { if (null == funcData) { return; } if (null != funcData) { if (type == "height") { foreach (var comp in funcData.Statements) { var callData = comp as Dsl.CallData; if (null != callData) { string id = callData.GetId(); if (id == "resettrees") { resetTrees = bool.Parse(callData.GetParamId(0)); } else if (id == "rect") { int x = int.Parse(callData.GetParamId(0)); int y = int.Parse(callData.GetParamId(1)); int w = int.Parse(callData.GetParamId(2)); int h = int.Parse(callData.GetParamId(3)); ProcessHeights(datas, calc, proc, x, y, w, h); } else if (id == "circle") { int x = int.Parse(callData.GetParamId(0)); int y = int.Parse(callData.GetParamId(1)); int r = int.Parse(callData.GetParamId(2)); ProcessHeights(datas, calc, proc, x, y, r); } } } } else if (type == "alphamap") { int alphanum = alphamaps.GetLength(2); foreach (var comp in funcData.Statements) { var callData = comp as Dsl.CallData; if (null != callData) { string id = callData.GetId(); if (id == "resettrees") { resetTrees = bool.Parse(callData.GetParamId(0)); } else if (id == "rect") { int x = int.Parse(callData.GetParamId(0)); int y = int.Parse(callData.GetParamId(1)); int w = int.Parse(callData.GetParamId(2)); int h = int.Parse(callData.GetParamId(3)); ProcessAlphamaps(alphamaps, calc, proc, x, y, w, h); } else if (id == "circle") { int x = int.Parse(callData.GetParamId(0)); int y = int.Parse(callData.GetParamId(1)); int r = int.Parse(callData.GetParamId(2)); ProcessAlphamaps(alphamaps, calc, proc, x, y, r); } } } } else if (type == "detail") { foreach (var comp in funcData.Statements) { var callData = comp as Dsl.CallData; if (null != callData) { string id = callData.GetId(); if (id == "resettrees") { resetTrees = bool.Parse(callData.GetParamId(0)); } else if (id == "rect") { int x = int.Parse(callData.GetParamId(0)); int y = int.Parse(callData.GetParamId(1)); int w = int.Parse(callData.GetParamId(2)); int h = int.Parse(callData.GetParamId(3)); ProcessDetails(details, calc, proc, x, y, w, h); } else if (id == "circle") { int x = int.Parse(callData.GetParamId(0)); int y = int.Parse(callData.GetParamId(1)); int r = int.Parse(callData.GetParamId(2)); ProcessDetails(details, calc, proc, x, y, r); } } } } } }
internal static void Process(GameObject root, Dsl.DslFile file, Dictionary <string, Color32[, ]> samplers, Dictionary <string, Size> cacheInfos) { if (null != file) { List <TreeInstance> trees = new List <TreeInstance>(); Dictionary <string, int[, ]> caches = new Dictionary <string, int[, ]>(); foreach (var pair in cacheInfos) { caches.Add(pair.Key, new int[pair.Value.Width, pair.Value.Height]); } var terrain = root.GetComponent <Terrain>(); var terrainData = terrain.terrainData; var datas = terrainData.GetHeights(0, 0, terrainData.heightmapWidth, terrainData.heightmapHeight); var alphamaps = terrainData.GetAlphamaps(0, 0, terrainData.alphamapWidth, terrainData.alphamapHeight); int alphanum = alphamaps.GetLength(2); int[] layers = terrainData.GetSupportedLayers(0, 0, terrainData.detailWidth, terrainData.detailHeight); Dictionary <int, int[, ]> details = new Dictionary <int, int[, ]>(); foreach (int layer in layers) { var ds = terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, layer); details.Add(layer, ds); } var calc = new Expression.DslCalculator(); calc.Init(); calc.Register("getheight", new Expression.ExpressionFactoryHelper <GetHeightExp>()); calc.Register("getalphamap", new Expression.ExpressionFactoryHelper <GetAlphamapExp>()); calc.Register("getalpha", new Expression.ExpressionFactoryHelper <GetAlphaExp>()); calc.Register("setalpha", new Expression.ExpressionFactoryHelper <SetAlphaExp>()); calc.Register("getdetail", new Expression.ExpressionFactoryHelper <GetDetailExp>()); calc.Register("samplered", new Expression.ExpressionFactoryHelper <SampleRedExp>()); calc.Register("samplegreen", new Expression.ExpressionFactoryHelper <SampleGreenExp>()); calc.Register("sampleblue", new Expression.ExpressionFactoryHelper <SampleBlueExp>()); calc.Register("samplealpha", new Expression.ExpressionFactoryHelper <SampleAlphaExp>()); calc.Register("getcache", new Expression.ExpressionFactoryHelper <GetCacheExp>()); calc.Register("setcache", new Expression.ExpressionFactoryHelper <SetCacheExp>()); calc.Register("addtree", new Expression.ExpressionFactoryHelper <AddTreeExp>()); calc.NamedVariables.Add("samplers", samplers); calc.NamedVariables.Add("caches", caches); calc.NamedVariables.Add("trees", trees); calc.NamedVariables.Add("heightscalex", terrainData.heightmapScale.x); calc.NamedVariables.Add("heightscaley", terrainData.heightmapScale.y); calc.NamedVariables.Add("heightscalez", terrainData.heightmapScale.z); calc.NamedVariables.Add("heights", datas); calc.NamedVariables.Add("alphamaps", alphamaps); calc.NamedVariables.Add("alphanum", alphanum); calc.NamedVariables.Add("details", details); calc.NamedVariables.Add("height", 0.0f); calc.NamedVariables.Add("alphas", new float[alphanum]); calc.NamedVariables.Add("detail", 0); bool resetTrees = false; bool canContinue = true; foreach (var info in file.DslInfos) { bool check = false; int num = info.GetFunctionNum(); if (num >= 2) { string firstId = info.First.GetId(); if (firstId == "input") { check = true; for (int i = 1; i < info.GetFunctionNum(); ++i) { string id = info.GetFunctionId(i); if (id == "height" || id == "alphamap" || id == "detail") { } else { check = false; break; } } } } if (!check) { canContinue = false; Debug.LogErrorFormat("error script:{0}, {1}", info.GetLine(), info.ToScriptString(false)); } } if (canContinue) { int ix = 0; foreach (var info in file.DslInfos) { for (int i = 1; i < info.GetFunctionNum(); ++i) { calc.Load(ix.ToString(), info.GetFunction(i)); ++ix; } } int ix2 = 0; foreach (var info in file.DslInfos) { for (int i = 1; i < info.GetFunctionNum(); ++i) { ProcessWithDsl(info.First, info.GetFunctionId(i), datas, alphamaps, details, calc, ix2.ToString(), ref resetTrees); ++ix2; } } } terrainData.SetHeights(0, 0, datas); terrainData.SetAlphamaps(0, 0, alphamaps); foreach (var pair in details) { terrainData.SetDetailLayer(0, 0, pair.Key, pair.Value); } if (resetTrees) { terrainData.treeInstances = trees.ToArray(); } else { trees.AddRange(terrainData.treeInstances); terrainData.treeInstances = trees.ToArray(); } } }