diff --git a/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemParser.cs b/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemParser.cs index 19349b1..6eeafa6 100644 --- a/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemParser.cs +++ b/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemParser.cs @@ -134,16 +134,22 @@ namespace ConsoleLSystem { var name = line.Substring(0, 1); var varable_index = new Dictionary(); if (line.Length > 1) { - foreach (var i in line.Substring(2, line.Length - 3).Split(',').Select((_name, Index) => new { _name, Index })) { - varable_index.Add(i._name, i.Index); + foreach (var i in line.Substring(2, line.Length - 3).Split(',').Select((name, Index) => new { name, Index })) { + varable_index.Add(i.name, i.Index); }; } return new LSystemNodeLiteralVariable(name, varable_index.Count, varable_index); } + //private static String[] parseIgnore(string line) { + // var items = line.Trim().Split(' '); + // var resut = List + + //} public static LSystemEvaluator parseLSystem(StreamReader sr) { string line; int line_number = 0; + var ignored = new String[0]; LSystemNode axiom = null; List rules = null; while ((line = sr.ReadLine()) != null) { @@ -155,12 +161,15 @@ namespace ConsoleLSystem { } axiom = parseWord(line,new LSystemWordBuilder()); } + if (line.Trim().Split(' ')[0].Trim() == "#ignore") { + ignored = line.Trim().Split(' ').Where(x=> x!= "#ignore" && x.Length>0).Select(x => x.Trim()).ToArray(); + } if (line.Trim() == "#rules") { rules = parseLSystemRules(sr); } } - return new LSystemEvaluator(axiom, rules); + return new LSystemEvaluator(axiom, rules, ignored); } private static List parseLSystemRules(StreamReader sr) { diff --git a/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemRule.cs b/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemRule.cs index ac58130..a8f7161 100644 --- a/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemRule.cs +++ b/unity_artifitial_world-st/Assets/Scripts/LSystem/LSystemRule.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace ConsoleLSystem { @@ -44,8 +45,8 @@ namespace ConsoleLSystem { } abstract public class LSystemRule { - abstract public bool is_aplicable(LSystemNode processed_node); - abstract public LSystemNode rewrite(LSystemNode processed_node); + abstract public bool is_aplicable(LSystemNode processed_node, String[] ignored); + abstract public LSystemNode rewrite(LSystemNode processed_node, String[] ignored); } public class LSystemRuleBasic : LSystemRule { @@ -57,7 +58,7 @@ namespace ConsoleLSystem { this.output = output; } - override public bool is_aplicable(LSystemNode processed_node) { + override public bool is_aplicable(LSystemNode processed_node, String[] ignored) { if (processed_node.literal == input) { return true; } @@ -65,8 +66,8 @@ namespace ConsoleLSystem { return false; } } - override public LSystemNode rewrite(LSystemNode processed_node) { - if (is_aplicable(processed_node)) { + override public LSystemNode rewrite(LSystemNode processed_node, String[] ignored) { + if (is_aplicable(processed_node, ignored)) { return output.deep_copy(); } else { @@ -86,7 +87,7 @@ namespace ConsoleLSystem { this.conditions = conditions; } - public override bool is_aplicable(LSystemNode processed_node) { + public override bool is_aplicable(LSystemNode processed_node, String[] ignored) { if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) { return false; } @@ -98,8 +99,8 @@ namespace ConsoleLSystem { return true; } - public override LSystemNode rewrite(LSystemNode processed_node) { - if (is_aplicable(processed_node)) { + public override LSystemNode rewrite(LSystemNode processed_node, String[] ignored) { + if (is_aplicable(processed_node, ignored)) { return consequent.eval(processed_node.literal.values); } else { @@ -140,7 +141,7 @@ namespace ConsoleLSystem { random = new Random(); } - public override bool is_aplicable(LSystemNode processed_node) { + public override bool is_aplicable(LSystemNode processed_node, String[] ignored) { if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) { return false; } @@ -152,7 +153,7 @@ namespace ConsoleLSystem { return true; } - public override LSystemNode rewrite(LSystemNode processed_node) { + public override LSystemNode rewrite(LSystemNode processed_node, String[] ignored) { var result = random.NextDouble(); int consequent_index = 0; for (int i = 0; i < probabilities.Length; i++) { @@ -161,7 +162,7 @@ namespace ConsoleLSystem { break; } } - if (is_aplicable(processed_node)) { + if (is_aplicable(processed_node, ignored)) { return consequents[consequent_index].eval(processed_node.literal.values); } else { @@ -196,20 +197,28 @@ namespace ConsoleLSystem { this.isPreceding = false; this.isSucceeding = true; } - public bool isAplicable(LSystemNode node,out float[] variables) { + public bool isAplicable(LSystemNode node, String[] ignored, out float[] variables) { var variables_list = new List(); - if (isPreceding && parent != node.parent.literal) { + var currentParent = node.parent; + while (ignored.Contains(currentParent.literal.name)) { + currentParent = currentParent.parent; + } + if (isPreceding && parent != currentParent.literal) { variables = new float[0]; return false; } if (isPreceding) { - variables_list.AddRange(node.parent.literal.values); + variables_list.AddRange(currentParent.literal.values); } variables_list.AddRange(node.literal.values); if (isSucceeding) { var result = false; LSystemNodeLiteral childLiteral; + Queue ignoredChildren = new Queue(); foreach(var child in node.getAllChildren()) { + if (ignored.Contains(child.literal.name)) { + ignoredChildren.Enqueue(child); + } if (child.literal == this.child) { childLiteral = child.literal; result = true; @@ -217,6 +226,20 @@ namespace ConsoleLSystem { break; } } + while (!result && ignoredChildren.Count>0) { + var ignoredChild = ignoredChildren.Dequeue(); + foreach (var child in ignoredChild.getAllChildren()) { + if (ignored.Contains(child.literal.name)) { + ignoredChildren.Enqueue(child); + } + if (child.literal == this.child) { + childLiteral = child.literal; + result = true; + variables_list.AddRange(child.literal.values); + break; + } + } + } if (!result) { variables = new float[0]; return false; @@ -237,12 +260,12 @@ namespace ConsoleLSystem { public LSystemRuleParametricStochasticContext(LSystemNodeLiteralVariable predecesor, MathExpressionComparison[] conditions, LSystemNodeGenerator consequent, LSystemContext context) : base(predecesor, conditions, consequent) { this.context = context; } - public override bool is_aplicable(LSystemNode processed_node) { + public override bool is_aplicable(LSystemNode processed_node,String[] ignored) { if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) { return false; } var variables = new float[0]; - if (!context.isAplicable(processed_node, out variables)) { + if (!context.isAplicable(processed_node, ignored, out variables)) { return false; } foreach (var condition in conditions) { @@ -252,12 +275,12 @@ namespace ConsoleLSystem { } return true; } - bool is_aplicable(LSystemNode processed_node, out float[] variables) { + bool is_aplicable(LSystemNode processed_node, String[] ignored, out float[] variables) { variables = new float[0]; if (processed_node.literal.name != predecesor.name || processed_node.literal.values_number != predecesor.values_number) { return false; } - if (!context.isAplicable(processed_node, out variables)) { + if (!context.isAplicable(processed_node, ignored, out variables)) { return false; } foreach (var condition in conditions) { @@ -268,16 +291,17 @@ namespace ConsoleLSystem { return true; } - public override LSystemNode rewrite(LSystemNode processed_node) { + public override LSystemNode rewrite(LSystemNode processed_node, String[] ignored) { var result = random.NextDouble(); int consequent_index = 0; for (int i = 0; i < probabilities.Length; i++) { if (result < probabilities[i]) { consequent_index = i; + break; } } float[] variables; - if (is_aplicable(processed_node, out variables)) { + if (is_aplicable(processed_node, ignored, out variables)) { return consequents[consequent_index].eval(variables); } else { diff --git a/unity_artifitial_world-st/Assets/Scripts/LSystem/MathExpression.cs b/unity_artifitial_world-st/Assets/Scripts/LSystem/MathExpression.cs index 5cea3d8..5f7b5fe 100644 --- a/unity_artifitial_world-st/Assets/Scripts/LSystem/MathExpression.cs +++ b/unity_artifitial_world-st/Assets/Scripts/LSystem/MathExpression.cs @@ -39,6 +39,7 @@ namespace ConsoleLSystem { private static Random random = new Random(); private static Dictionary expression_hierarchy = new Dictionary{ + {'^', 4}, {'*', 3}, {'/', 3}, {'+', 1}, @@ -54,6 +55,9 @@ namespace ConsoleLSystem { private static float mulitply(float[] children, float[] variables) { return children[0] * children[1]; } + private static float power(float[] children, float[] variables) { + return (float)Math.Pow(children[0],children[1]); + } private static float divide(float[] children, float[] variables) { return children[0] / children[1]; } @@ -135,6 +139,9 @@ namespace ConsoleLSystem { case '-': return new MathExpressionNode(subtract, child_nodes); break; + case '^': + return new MathExpressionNode(power, child_nodes); + break; default: throw new Exception(String.Format("unknown operation {0} in {1}", expression_string[expression_pos], expression_string)); break; diff --git a/unity_artifitial_world-st/Assets/Scripts/LSystem/Program.cs b/unity_artifitial_world-st/Assets/Scripts/LSystem/Program.cs index 13e2b86..da44fae 100644 --- a/unity_artifitial_world-st/Assets/Scripts/LSystem/Program.cs +++ b/unity_artifitial_world-st/Assets/Scripts/LSystem/Program.cs @@ -141,15 +141,22 @@ namespace ConsoleLSystem { public class LSystemEvaluator { public LSystemNode lSystemString { get; set; } public List lSystemRules { get; set; } + public String[] ignored { get; set; } public LSystemEvaluator(LSystemNode startingString, List rules) { lSystemString = startingString; lSystemRules = rules; + ignored = new String[0]; + } + public LSystemEvaluator(LSystemNode startingString, List rules, String[] ignored) { + lSystemString = startingString; + lSystemRules = rules; + this.ignored = ignored; } private LSystemNode _rewrite(LSystemNode node) { foreach (var rule in lSystemRules) { - if (rule.is_aplicable(node)) { - return rule.rewrite(node); + if (rule.is_aplicable(node, ignored)) { + return rule.rewrite(node, ignored); } } return new LSystemNode(node.literal); diff --git a/unity_artifitial_world-st/Assets/Scripts/TurtleLSystem.cs b/unity_artifitial_world-st/Assets/Scripts/TurtleLSystem.cs index 65b3bd4..e3211bf 100644 --- a/unity_artifitial_world-st/Assets/Scripts/TurtleLSystem.cs +++ b/unity_artifitial_world-st/Assets/Scripts/TurtleLSystem.cs @@ -77,7 +77,14 @@ abstract public class TurtleLSystem : MonoBehaviour Debug.Log(evaluator.lSystemString.ToString()); } private GameObject prepeareGameObject(string name, GameObject gameObject,Matrix4x4 transformation) { - var instance = Instantiate(gameObject); + GameObject instance; + if (PrefabUtility.GetPrefabAssetType(gameObject) != PrefabAssetType.NotAPrefab) { + instance = Instantiate(gameObject); + } + else { + instance = gameObject; + } + instance.name = String.Format("LSystem Literal {0}", name); instance.tag = "LSystemLiteral"; instance.transform.parent = this.gameObject.transform;