using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; using ConsoleLSystem; using System; abstract public class TurtleLSystemEnvironment : TurtleLSystem { public Environment environment; // private LSystemEvaluator evaluator = null; // private float nextStep; public sbyte shadowStrength; public int lookForLightAngle = 35; public float lookForLightLength = 2.0f; public Matrix4x4 lightDirection(Matrix4x4 transformation, Matrix4x4 resultTransformation, GameObject shape, LSystemNode node) { int minShadow = 10000; Matrix4x4 bestTransformation = transformation; int maxShadowTries = 20; int shadowRotate = 360/20; int shadowStrength_ = 0; bool clearShape = false; if(shape == null) { clearShape = true; shape = new GameObject("ShadowConeShape"); } GameObject instance; Matrix4x4 new_transformation = transformation; foreach (GameObject gameObject in GameObject.FindGameObjectsWithTag("ShadowCone")) { DestroyImmediate(gameObject); } Matrix4x4 objectTransformation = (transformation*resultTransformation); int nr_shadow_str = 1; //---------------------miejsce-na-zadanie-3.4--------------------------------------// int result = 0, count = 0; for(float x = -lookForLightLength; x < lookForLightLength; x = x + 0.5f){ for(float y = 0; y < lookForLightLength; y = y + 0.5f){ for(float z = -lookForLightLength; z < lookForLightLength; z = z + 0.5f){ Matrix4x4 matrix = objectTransformation * Matrix4x4.Translate(new Vector3(x, y, z)); result = result + environment.shadowStrength(matrix.ExtractPosition()); count++; } } } nr_shadow_str = result / count; //---------------------miejsce-na-zadanie-3.4-koniec-------------------------------// if (environment.sendShadowToLSystem) { //---------------------miejsce-na-zadanie-3.5--------------------------------------// if(node.literal.name == "S"){ node.literal.values[1] = node.literal.values[1] + nr_shadow_str; } //---------------------miejsce-na-zadanie-3.5-koniec------------------------------// } bestTransformation = transformation*resultTransformation; if(environment.rotateTowardsLight) { minShadow = shadowStrength_; if(shadowStrength_/nr_shadow_str > 5.0f) { shadowConeLimiter ++; // transformation = Matrix4x4.Translate(gameObject.transform.position)*transformation; for(int angle = 0;angle <= lookForLightAngle;angle+=10) { for(int i = 0; i < 360; i += shadowRotate) { shadowStrength_ = 0; for(float length = 0.5f; length 220*lookForLightLength*2.0f) { bestTransformation = Matrix4x4.Translate(new Vector3(0,0,0)); } } if(clearShape) { DestroyImmediate(shape); } return bestTransformation; } public void evaluate() { base.evaluate(); } public void evaluateAndPresent() { evaluate(); present(); // Debug.Log(evaluator.lSystemString.ToString().Length); //x.name = "aaa"; //Instantiate(x,Matrix4x4.identity); } public void loadFile() { // nextStep = Time.time; // clearObjects(); var sr = new StreamReader(LSystemPath); evaluator = LSystemFileParser.parseLSystem(sr); sr.Close(); turtleInterpretation = new Dictionary>>(); initLiteralInterpretation(); } public void present() { clearObjects(); createModelsRecursiveInEnviroment(evaluator.lSystemString, Matrix4x4.Translate(gameObject.transform.position/2.0f));//Matrix4x4.identity); } void refreshShadows() { environment.Reset(); foreach (GameObject gameObject in GameObject.FindGameObjectsWithTag("LSystemLiteral")) { // if(!isParentThisGameObject(gameObject)) // { environment.addShadow(gameObject.GetComponent().position, shadowStrength); // } // else // { // if(isParentThisGameObject(gameObject, 2)) // { // environment.addShadowPoint(gameObject.GetComponent().position, 6); // } // } } } bool isParentThisGameObject(GameObject gameObject, int depth = 3) { if(gameObject.transform.parent != null) { if(gameObject.transform.parent.gameObject == this.gameObject) { return true; } else { if(depth >= 0) { return isParentThisGameObject(gameObject.transform.parent.gameObject, depth-1); } } } return false; } int objectCounter = 0; int shadowConeLimiter = 0; public int childrenCount(LSystemNode node, int depth = 3) { int c = 0; if(node.children.Count > 0) { c += node.children.Count; if(depth > 0) { foreach(LSystemNode child in node.children) { c+= childrenCount(child, depth - 1); } } } return c; } public void createModelsRecursiveInEnviroment(LSystemNode node, Matrix4x4 transformation, int depth = 0) { // transformation *= Matrix4x4.Translate(gameObject.transform.position); while (node != null && objectCounter < 25000) { 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); Debug.Log("D: "+node.literal); new_transformation = new_transformation*Matrix4x4.Rotate(Quaternion.Euler(UnityEngine.Random.Range(-0.5f, 0.5f), UnityEngine.Random.Range(-0.5f, 0.5f), UnityEngine.Random.Range(-0.5f, 0.5f))); new_transformation = lightDirection(new_transformation, result.Item2, result.Item1, node); if(new_transformation == Matrix4x4.Translate(new Vector3(0,0,0)) && environment.cutBranchesWithMaxShadow) { Debug.Log(" children "+node.children.Count); // node.literal. if(childrenCount(node) < 5) { LSystemNode destroyNode = node; if(destroyNode.parent != null) { destroyNode.parent.children.Remove(node); if(destroyNode.parent.mainChild == null) { destroyNode.parent.mainChild = destroyNode.parent.children[0]; } node = node.mainChild; destroyNode = null; // DestroyImmediate(instance); objectCounter--; } continue; } } if (result.Item1 != null && new_transformation != Matrix4x4.Translate(new Vector3(0,0,0))) { var instance = this.prepeareGameObject(name, result.Item1, new_transformation); environment.addShadow(new_transformation.ExtractPosition()+transformation.MultiplyPoint(result.Item1.transform.position), (sbyte)(shadowStrength/8.0f)); } environment.addShadow(new_transformation.ExtractPosition()+transformation.ExtractPosition(), (sbyte)(shadowStrength/8.0f)); environment.addShadow((new_transformation*Matrix4x4.Translate(new Vector3(0,1,0))).ExtractPosition()+transformation.ExtractPosition(), (sbyte)(shadowStrength/8.0f)); //remove scale, rather unnecesary new_transformation = new_transformation * Matrix4x4.Scale(result.Item2.ExtractScale()).inverse; } if(node != null) { List children_tmp = new List(); foreach (var child in node.children) { children_tmp.Add(child); } foreach (var child in children_tmp) { if(child != null) { createModelsRecursiveInEnviroment(child, new_transformation, depth+1); } } 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); // // } objectCounter = 0; int removed = 1; while (removed > 0) { removed = 0; foreach (Transform child in this.gameObject.transform) { // environment.addShadow(gameObject.GetComponent().position, (sbyte)-shadowStrength); if(child.gameObject.tag == "LSystemLiteral") { DestroyImmediate(child.gameObject); } removed ++; // GameObject.Destroy(child.gameObject); } } refreshShadows(); // gameObjects = new List(); } }