using System; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; abstract public class TurtleLSystem : MonoBehaviour { public float speed; private float nextStep; public string LSystemPath; public uint steps; public Dictionary>> turtleInterpretation = new Dictionary>>(); private List gameObjects = new List(); private bool isAnimationRunning = false; private Mesh getCylinder(int quality, float width, float length) { Mesh mesh = new Mesh(); //mesh.triangles var points = new List(); var normals = new List(); var indices = new List(); for (float i = 0; i < quality; i++) { points.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, 0, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width)); } for (float i = 0; i < quality; i++) { points.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, length, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width)); } //points.Add(new Vector3(0,0,0)); //points.Add(new Vector3(0, length, 0)); for (float i = 0; i < quality; i++) { normals.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, 0, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width)); } for (float i = 0; i < quality; i++) { normals.Add(new Vector3(Mathf.Cos((i / quality) * 2 * Mathf.PI) * width, 0, Mathf.Sin((i / quality) * 2 * Mathf.PI) * width)); } //for (int i = 0; i < quality; i++) { // indices.Add(i); // indices.Add((i + 1) % quality); // indices.Add(quality * 2); //} //for (int i = 0; i < quality; i++) { // indices.Add((i + 1) % quality + quality); // indices.Add(i + quality); // indices.Add(quality * 2 + 1); //} for (int i = 0; i < quality; i++) { indices.Add((i + 1) % quality); indices.Add(i); indices.Add(i + quality); indices.Add(i + quality); indices.Add((i + 1) % quality + quality); indices.Add((i + 1) % quality); } mesh.vertices = points.ToArray(); mesh.triangles = indices.ToArray(); mesh.normals = normals.ToArray(); return mesh; } protected LSystemEvaluator evaluator = null; private void parseRules(StreamReader sr) { } public void evaluate() { for (int i = 0; i < steps; i++) { evaluator.rewrite(); } Debug.Log(evaluator.lSystemString.ToString()); } protected GameObject prepeareGameObject(string name, GameObject gameObject, Matrix4x4 transformation) { 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; instance.transform.position = transformation.ExtractPosition() + transformation.MultiplyPoint(instance.transform.position); instance.transform.rotation *= transformation.ExtractRotation(); instance.transform.localScale = Vector3.Scale(transformation.ExtractScale(), instance.transform.localScale); return instance; } public void createModelsRecursive(LSystemNode node, Matrix4x4 transformation) { while (node != null) { Matrix4x4 new_transformation = transformation; Func> interpretation; var name = node.literal.name; if (turtleInterpretation.TryGetValue(name, out interpretation) || turtleInterpretation.TryGetValue("*.*", out interpretation)) { var result = interpretation(node.literal.values); new_transformation = new_transformation * result.Item2; if (result.Item1 != null) { var instance = prepeareGameObject(name, result.Item1, new_transformation); } //gameObjects.Add(gameObject); //remove scale, rather unnecesary new_transformation = new_transformation * Matrix4x4.Scale(result.Item2.ExtractScale()).inverse; } foreach (var child in node.children) { createModelsRecursive(child, new_transformation); } node = node.mainChild; transformation = new_transformation; } } private void clearObjects() { //var objects = Resources.FindObjectsOfTypeAll().Where(obj => obj.name == "Name"); foreach (GameObject gameObject in GameObject.FindGameObjectsWithTag("LSystemLiteral")) { DestroyImmediate(gameObject); } Debug.Log("#OldClear"); gameObjects = new List(); } public void present() { clearObjects(); createModelsRecursive(evaluator.lSystemString, Matrix4x4.identity); } abstract protected void initLiteralInterpretation(); public void loadFile() { nextStep = Time.time; clearObjects(); var sr = new StreamReader(LSystemPath); evaluator = LSystemFileParser.parseLSystem(sr); sr.Close(); turtleInterpretation = new Dictionary>>(); initLiteralInterpretation(); } public void evaluateAndPresent() { evaluate(); present(); Debug.Log(evaluator.lSystemString.ToString().Length); //x.name = "aaa"; //Instantiate(x,Matrix4x4.identity); } public void switchAnimation() { this.isAnimationRunning = !this.isAnimationRunning; nextStep = Time.time; } void runAnimation() { if (nextStep < Time.time) { for (int i = 0; i < (Time.time - nextStep) * speed; i++) { evaluator.rewrite(); } present(); nextStep = Time.time + 1 / speed; } } // Update is called once per frame protected virtual void Update() { if (this.isAnimationRunning) { this.runAnimation(); } } }